feedback5: merge W5AA — community reports of 2026-10-06: the 孤岛风云 prisoners leave the gate confined (grey) and change model as their prefabs do, the 4th attack hits freed; a bounty enemy that dies with no operator behind it pays in 联防 too (the helper whose half it fell on); 忍冬's trigger and 枯朽之种's bounty were already fixed (pinned by tests); DESIGN §25.14 after round 18's §25.13; data/enemies.json regenerated offline on the merged code (round 18's model quirks + the prisoners' clips); golden: vs feedback5 exactly W5AA's moves (26 battles, solo-ABYSS-2, coop2-NORMAL-3, coop3-ABYSS-5, solo-HARD-9-boosted), vs W5AA exactly round 18's boss-pool moves

This commit is contained in:
sganggs committed 2026-10-06 22:35:10 +08:00
commit 714af994fc
26 files changed
+1081 -366

No files matched your search

+1 -1
View File
@@ -1 +1 @@
{"version":1,"hash":"026eaf9ff08e","generator":"tools/fetch-assets.mjs","stats":{"files":7972,"bytes":485093753,"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},"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/front/char_017_huang.skelLine truncated
{"version":1,"hash":"65d6d7dc722e","generator":"tools/fetch-assets.mjs","stats":{"files":7972,"bytes":485093753,"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},"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/front/char_017_huang.skelLine truncated
+1 -1
View File
@@ -1 +1 @@
{"enemy_1000_gopro_2":{"key":"enemy_1000_gopro_2","name":"猎狗pro","level":0,"rank":"NORMAL","handbookIndex":"O2","desc":"比一般猎狗更具有作战能力,行动速度很快。","descRaw":"比一般猎狗更具有作战能力,<@eb.key>行动速度很快</>。","applyWay":"MELEE","stats":{"maxHp":1700,"atk":260,"def":0,"res":20,"moveSpeed":1.9,"bat":1.4,"aspd":100,"rangeRadius":0,"rawRangeRadius":0,"blockCnt":1,"massLevel":0,"lpr":1,"hpRecoveryPerSec":0,"elementRes":0,"elementDmgRes":0,"hitRatePhys":0,"hitRateArts":0,"dmgType":"phys","dmgTypes":["phys"],"motion":"WALK","immunities":{"stun":false,"silence":false,"sleep":false,"frozen":false,"levitate":false},"otherImmunities":[],"tauntLevel":0},"abilities":[],"talents":{"bb":{},"bbStr":{}},"skills":[],"notCountInTotal":false,"tags":["infection"],"be":3060,"beFactor":1,"attrPower":3060,"isFlyEnemy":false,"tokenOnly":false,"acTypes":["SPECIAL"],"acType":"SPECIAL","templateSlot":"T","summons":[],"inactiveIn":[],"seasonOverride":null,"iconId":"enemy_1000_gopro_2","spine":"enemy_1000_gopro_2","modelScale":0.963,"attackAnim":{"clip":"Attack","dur":1,"hit":0.6}},"enemy_1001_bigbo":{"key":"enemy_1001_bigbo","name":"大鲍勃","level":0,"rank":"BOSS","handbookIndex":"11","desc":"整合运动的特殊近战人员,使用电锯进行攻击,兼具高耐久、攻击力和防御力。","descRaw":"整合运动的特殊近战人员,使用电锯进行攻击,兼具<@eb.danger>高耐久、攻击力和防御力</>。","applyWay":"MELEE","stats":{"maxHp":22000,"atk":1900,"def":800,"res":30,"moveSpeed":0.5,"bat":6,"aspd":100,"rangeRadius":0,"rawRangeRadius":0,"blockCnt":1,"massLevel":4,"lpr":1,"hpRecoveryPerSec":0,"elementRes":0,"elementDmgRes":0,"hitRatePhys":0,"hitRateArts":0,"dmgType":"phys","dmgTypes":["phys"],"motion":"WALK","immunities":{"stun":false,"silence":false,"sleep":false,"frozen":false,"levitate":false},"otherImmunities":[],"tauntLevel":0},"abilities":[],"talents":{"bb":{},"bbStr":{}},"skills":[],"notCountInTotal":false,"tags":[],"be":33990,"beFactor":1,"attrPower":33990,"isFlyEnemy":false,"tokenOnly":false,"acTypes":[],"acType":null,"templateSlot":null,"summons":[],"inactiveIn":[],"seasonOverride":null,"iconId":"enemy_1001_bigbo","spine":"enemy_1001_bigbo","modelScale":1.1111,"attackAnim":{"clip":"Attack","dur":1,"hit":0.167}},"enemy_1005_yokai":{"key":"enemy_1005_yokai","name":"妖怪","level":0,"rank":"NORMAL","handbookIndex":"D1","desc":"【飞行单位】敌方人员操纵的无人机,不会进行攻击。","descRaw":"<@eb.key>【飞行单位】</>敌方人员操纵的无人机,不会进行攻击。","applyWay":"NONE","stats":{"maxHp":800,"atk":0,"def":50,"res":0,"moveSpeed":0.9,"bat":2.3,"aspd":100,"rangeRadius":0,"rawRangeRadius":0,"blockCnt":1,"massLevel":0,"lpr":1,"hpRecoveryPerSec":0,"elementRes":0,"elementDmgRes":0,"hitRatePhys":0,"hitRateArts":0,"dmgType":"none","dmgTypes":["none"],"motion":"FLY","immunities":{"stun":false,"silence":false,"sleep":false,"frozen":false,"levitate":false},"otherImmunities":[],"tauntLevel":0},"abilities":[{"text":"飞行单位","textRaw":"飞行单位","format":"NORMAL"}],"talents":{"bb":{},"bbStr":{}},"skills":[],"notCountInTotal":false,"tags":["drone"],"be":950,"beFactor":1,"attrPower":950,"isFlyEnemy":true,"tokenOnly":false,"acTypes":["FLY"],"acType":"FLY","templateSlot":"NF","summons":[],"inactiveIn":[],"seasonOverride":null,"iconId":"enemy_1005_yokai","spine":"enemy_1005_yokai","staticBody":true,"modelScale":0.7407,"attackAnim":{"clip":"Attack","dur":1,"hit":0.267}},"enemy_1005_yokai_2":{"key":"enemy_1005_yokai_2","name":"妖怪MKII","level":0,"rank":"NORMAL","handbookIndex":"D2","desc":"【飞行单位】妖怪的改进版,可进行远程物理射击。","descRaw":"<@eb.key>【飞行单位】</>妖怪的改进版,可进行<@eb.key>远程物理射击</>。","applyWay":"RANGED","stats":{"maxHp":1550,"atk":220,"def":50,"res":0,"moveSpeed":0.9,"bat":3,"aspd":100,"rangeRadius":2,"rawRangeRadius":2,"blockCnt":1,"massLevel":0,"lpr":1,"hpRecoveryPerSec":0,"elementRes":0,"elementDmgRes":0,"hitRatePhys":0,"hitRateArts":0,"dmgType":"phys","dmgTypes":["phys"],"motion":"FLY","immunities":{"stun":false,"silence":false,"sleep":false,"frozen":false,"levitate":false},"otherImmunities":[],"tauntLevel":0},"abilities":[{"text":"飞行单位","textRaw":"飞行单位","format":"NORMAL"}],"talents":{"bb":{},"bbStr":{}},"skills":[],"notCountInTotal":false,"tags":["drone"],"be":4000,"beFactor":0.7,"attrPower":2800,"isFlyEnemy":true,"tokenOnly":false,"acTypes":["FLY"],"acType":"FLY","templateSlot":null,"summons":[],"inactiveIn":[],"seasonOverride":null,"iconId":"enemy_1005_yokai_2","spine":"enemy_1005_yokai_2","staticBody":true,"modelScale":0.8148,"attackAnim":{"clip":"Attack","dur":1,"hit":0.267}},"enemy_1005_yokai_3":{"key":"enemy_1005_yokai_3","name":"威龙","level":0,"rank":"ELITE","handbookIndex":"D3","desc":"【飞行单位】大型无人机,拥有更好的耐久性能,可进行远程物理射击。","descRawLine truncated
{"enemy_1000_gopro_2":{"key":"enemy_1000_gopro_2","name":"猎狗pro","level":0,"rank":"NORMAL","handbookIndex":"O2","desc":"比一般猎狗更具有作战能力,行动速度很快。","descRaw":"比一般猎狗更具有作战能力,<@eb.key>行动速度很快</>。","applyWay":"MELEE","stats":{"maxHp":1700,"atk":260,"def":0,"res":20,"moveSpeed":1.9,"bat":1.4,"aspd":100,"rangeRadius":0,"rawRangeRadius":0,"blockCnt":1,"massLevel":0,"lpr":1,"hpRecoveryPerSec":0,"elementRes":0,"elementDmgRes":0,"hitRatePhys":0,"hitRateArts":0,"dmgType":"phys","dmgTypes":["phys"],"motion":"WALK","immunities":{"stun":false,"silence":false,"sleep":false,"frozen":false,"levitate":false},"otherImmunities":[],"tauntLevel":0},"abilities":[],"talents":{"bb":{},"bbStr":{}},"skills":[],"notCountInTotal":false,"tags":["infection"],"be":3060,"beFactor":1,"attrPower":3060,"isFlyEnemy":false,"tokenOnly":false,"acTypes":["SPECIAL"],"acType":"SPECIAL","templateSlot":"T","summons":[],"inactiveIn":[],"seasonOverride":null,"iconId":"enemy_1000_gopro_2","spine":"enemy_1000_gopro_2","modelScale":0.963,"attackAnim":{"clip":"Attack","dur":1,"hit":0.6}},"enemy_1001_bigbo":{"key":"enemy_1001_bigbo","name":"大鲍勃","level":0,"rank":"BOSS","handbookIndex":"11","desc":"整合运动的特殊近战人员,使用电锯进行攻击,兼具高耐久、攻击力和防御力。","descRaw":"整合运动的特殊近战人员,使用电锯进行攻击,兼具<@eb.danger>高耐久、攻击力和防御力</>。","applyWay":"MELEE","stats":{"maxHp":22000,"atk":1900,"def":800,"res":30,"moveSpeed":0.5,"bat":6,"aspd":100,"rangeRadius":0,"rawRangeRadius":0,"blockCnt":1,"massLevel":4,"lpr":1,"hpRecoveryPerSec":0,"elementRes":0,"elementDmgRes":0,"hitRatePhys":0,"hitRateArts":0,"dmgType":"phys","dmgTypes":["phys"],"motion":"WALK","immunities":{"stun":false,"silence":false,"sleep":false,"frozen":false,"levitate":false},"otherImmunities":[],"tauntLevel":0},"abilities":[],"talents":{"bb":{},"bbStr":{}},"skills":[],"notCountInTotal":false,"tags":[],"be":33990,"beFactor":1,"attrPower":33990,"isFlyEnemy":false,"tokenOnly":false,"acTypes":[],"acType":null,"templateSlot":null,"summons":[],"inactiveIn":[],"seasonOverride":null,"iconId":"enemy_1001_bigbo","spine":"enemy_1001_bigbo","modelScale":1.1111,"attackAnim":{"clip":"Attack","dur":1,"hit":0.167}},"enemy_1005_yokai":{"key":"enemy_1005_yokai","name":"妖怪","level":0,"rank":"NORMAL","handbookIndex":"D1","desc":"【飞行单位】敌方人员操纵的无人机,不会进行攻击。","descRaw":"<@eb.key>【飞行单位】</>敌方人员操纵的无人机,不会进行攻击。","applyWay":"NONE","stats":{"maxHp":800,"atk":0,"def":50,"res":0,"moveSpeed":0.9,"bat":2.3,"aspd":100,"rangeRadius":0,"rawRangeRadius":0,"blockCnt":1,"massLevel":0,"lpr":1,"hpRecoveryPerSec":0,"elementRes":0,"elementDmgRes":0,"hitRatePhys":0,"hitRateArts":0,"dmgType":"none","dmgTypes":["none"],"motion":"FLY","immunities":{"stun":false,"silence":false,"sleep":false,"frozen":false,"levitate":false},"otherImmunities":[],"tauntLevel":0},"abilities":[{"text":"飞行单位","textRaw":"飞行单位","format":"NORMAL"}],"talents":{"bb":{},"bbStr":{}},"skills":[],"notCountInTotal":false,"tags":["drone"],"be":950,"beFactor":1,"attrPower":950,"isFlyEnemy":true,"tokenOnly":false,"acTypes":["FLY"],"acType":"FLY","templateSlot":"NF","summons":[],"inactiveIn":[],"seasonOverride":null,"iconId":"enemy_1005_yokai","spine":"enemy_1005_yokai","staticBody":true,"modelScale":0.7407,"attackAnim":{"clip":"Attack","dur":1,"hit":0.267}},"enemy_1005_yokai_2":{"key":"enemy_1005_yokai_2","name":"妖怪MKII","level":0,"rank":"NORMAL","handbookIndex":"D2","desc":"【飞行单位】妖怪的改进版,可进行远程物理射击。","descRaw":"<@eb.key>【飞行单位】</>妖怪的改进版,可进行<@eb.key>远程物理射击</>。","applyWay":"RANGED","stats":{"maxHp":1550,"atk":220,"def":50,"res":0,"moveSpeed":0.9,"bat":3,"aspd":100,"rangeRadius":2,"rawRangeRadius":2,"blockCnt":1,"massLevel":0,"lpr":1,"hpRecoveryPerSec":0,"elementRes":0,"elementDmgRes":0,"hitRatePhys":0,"hitRateArts":0,"dmgType":"phys","dmgTypes":["phys"],"motion":"FLY","immunities":{"stun":false,"silence":false,"sleep":false,"frozen":false,"levitate":false},"otherImmunities":[],"tauntLevel":0},"abilities":[{"text":"飞行单位","textRaw":"飞行单位","format":"NORMAL"}],"talents":{"bb":{},"bbStr":{}},"skills":[],"notCountInTotal":false,"tags":["drone"],"be":4000,"beFactor":0.7,"attrPower":2800,"isFlyEnemy":true,"tokenOnly":false,"acTypes":["FLY"],"acType":"FLY","templateSlot":null,"summons":[],"inactiveIn":[],"seasonOverride":null,"iconId":"enemy_1005_yokai_2","spine":"enemy_1005_yokai_2","staticBody":true,"modelScale":0.8148,"attackAnim":{"clip":"Attack","dur":1,"hit":0.267}},"enemy_1005_yokai_3":{"key":"enemy_1005_yokai_3","name":"威龙","level":0,"rank":"ELITE","handbookIndex":"D3","desc":"【飞行单位】大型无人机,拥有更好的耐久性能,可进行远程物理射击。","descRawLine truncated
+9 -1
View File
@@ -129,6 +129,10 @@ The `stem` of a Spine model is the upstream file name. Two examples: `char_107_l
- The parse extracts animation names and durations, event names, `OnAttack` times per animation, and bounds.
- Attachment paths are checked against the atlas regions.
- Then the animation-role resolver runs. See `tools/assets/anim-roles.mjs` and research 07 §5.4.
- A web enemy model whose clip names mislead the resolver gets the roles of its official battle prefab
(`tools/assets/spine.mjs PREFAB_SPINE_ROLES`, read from the local client's `battle/enm_pfb_*.ab`: the prefab's anim
key → clip table and the clip its Spine starts on): 普通囚犯 / 老练囚犯 start on their grey `*3` set (【禁锢】), not
the unnumbered red one (【解放】) the names point to.
- **Fonts:** OTF/TTF files are converted to WOFF2 by a built-in encoder (`tools/assets/woff2.mjs`: Brotli with null transforms).
- Its output was verified lossless against Google's reference `woff2` decoder.
- `fonts.css` lists WOFF2 first and falls back to the original file.
@@ -259,7 +263,7 @@ The resolver's full precedence list is in the header of `tools/assets/anim-roles
The manifest roles describe a unit's first form. Units whose skeleton holds another form's clip set get it from
`public/js/render/units.js FORMS` (keyed by Spine id, switched by the `form` of the sim's 'phase' / 'ember' / 'revive'
/ 'telegraph' / 'stone' / 'substitute' / 'swap' / 'dollEnd' fx — `shared/protocol.js fxForm`; no client stage drops these fx: the runner keeps them through
/ 'telegraph' / 'stone' / 'liberate' / 'substitute' / 'swap' / 'dollEnd' fx — `shared/protocol.js fxForm`; no client stage drops these fx: the runner keeps them through
catch-up frames and hidden tabs (`keepsState`), the game screen's pre-entry buffer (`keepEarly`) and the render engine's
event queue (`render/interp.js isCosmeticEvent`) too — or, for a view built mid-battle, UnitInfo `form`, which `render/app/info.js renderInfo` passes to the view; a
`change` clip plays once first, an `end` clip is timed from the fx's `dur` to finish as that state ends, keeping the
@@ -272,6 +276,10 @@ stealth bit only while its 隐匿 is on:
- the leaders' 重生: 锏 (`Revive1`, `Revive2` held, `Revive3`, then `B_*`), 扎罗 (`A_revive_1` / `_2` / `_3`, then `B_*`),
“复仇者” (`Revive_Begin` / `_Loop` / `_End`), 杰斯顿 (`C1_Die`, then `C2_*`);
- 守墓石像 (the statue on `Sleep` [ASSUMED by name], then the flyer's `*_2`).
- the 孤岛风云 prisoners, as their official prefabs' modes: confined on the manifest's grey set, `warning` (mode R, the
warning before the last confined attack) on the blinking orange set, `liberty` (【解放】) on the red set — 普通囚犯 /
老练囚犯 `Idle3` → `Idle2` → `Idle`, 强壮囚犯 `Idle` → `Idle2` → `Idle3`, 拳师囚犯 / 重犯 / 传奇重犯 `*_grey` → `*_orange` →
`*_red` (Move / Attack / Die alike; no change clip).
- the 傀儡师 operators' <替身> (form `doll` of the sim's 'substitute' / 'swap' / 'dollEnd' fx, DESIGN §22.11; the `*_B`
clips draw the 替身's own slots and hide the 本体's): 归溟幽灵鲨 `Start_B` (it fades in), `Idle_B`, `Die_B` over its last
second (it breaks apart and fades), `Die_B_2` when it is knocked out (it collapses), and the 本体 back on `Start_2` (a
+1 -1
View File
@@ -622,7 +622,7 @@ Any `choice:` handler whose EffectRef reuses its own key must guard like this (o
default 2). Read as game seconds the rounds' own spawn schedules would not fit (R2's last flyer spawns at 43 s of
45 s, R3's at 62 s of 55 s); × 2 every limit ≈ last spawn + one flyer crossing. docs/BALANCE.md §2.1.
* **SETTLE**: LP −min(counted leaks, 10) (after 联防: survivors attributed to their source, same cap); IN_BATTLE layer
gains applied, each bond up to `BOND_LAYER_CAP` (999, `layerGainRoom`, as `PlayerState.addLayers`); kill-bounty coins (paid by the Battle to the killer — a 联防 helper included) and perfect-bounty coins
gains applied, each bond up to `BOND_LAYER_CAP` (999, `layerGainRoom`, as `PlayerState.addLayers`); kill-bounty coins (paid by the Battle to the killer — a 联防 helper included; a death no operator caused pays the card's owner, in 联防 the helper whose half it fell on: `Battle._bountyPayee`) and perfect-bounty coins
(own phase perfect) go to pending funds; bounty rounds decrement; LP ≤ 0 ⇒ eliminated (all copies back to the pool).
* **Final Assault / Hidden Core**: finalAssault.js header. Boards are passed in board coordinates; the sim maps board
rows 9–12 onto boss rows 2–5 (`BOSS_ROW_OFFSET` −7, matching every stage's boss rows) and mirrors the right side.
+1 -1
View File
@@ -92,7 +92,7 @@
- 联防在官方的**联防专用地图**上进行(与官方相同,不是本回合的战场):一整片道路,没有水池、箱子、装置等地形;干员按休整期的位置站好。一人协防时敌人从中间的入口进入左半场;两人协防时敌人从最右侧进入,先经过右半场,再穿过中间进入左半场。
- 只有完美作战的队友能参与联防;联防中**盟约不会叠加层数**。
- 联防中击杀悬赏敌人,资金归击杀者。
- 联防中击杀悬赏敌人,资金归击杀者;没有干员击倒它时(无来源伤害、它自己扣血、其他敌人的伤害等),资金归它倒下处所在半场的队友。悬赏敌人在自己的战场上被地形(如活性源石)烫死,资金照样归你。
- 联防后仍然存活的敌人,按原主人扣 LP;没人完美作战时直接扣。
- 漏怪的玩家在顶栏中间(击倒数旁)看到橙色的「×N」标签:你漏过、仍在联防战场上的敌人数(含还没出场的,**不设上限**),队友每击倒一个就减一(会分裂或召唤的敌人被击倒时,分裂出的敌人也算你的,数字会相应增加);目标生命值同时显示为扣除 min(N, 10) 后的数值。左侧队伍栏里漏怪队友的行也显示 ×N(与战场上的击倒同步更新;鼠标悬停可看到是谁漏过的敌人)。
- **有敌人走进蓝门就会响一声**:不等它真的扣到目标生命值——一回合里超过 10 点上限的那部分、数据里标明不计数目的敌人(BOSS 部件之类),以及联防里漏过去、随后被队友清掉的那几只,目标生命值都不会再扣,但这一声照样会响。播的是**原版关卡里怪进蓝门那一声**(官方音效表里的 `ON_ENEMY_REACHED_EXIT`,任何一关都是它)。你正在看哪个战场就听哪个战场的,所以看队友的战场、以及漏怪后观看联防时同样听得到。这一声 1.44 秒,我们按官方的「同时只允许一个」做成 **1.5 秒内共用一声**:一波打穿防线只响一遍(不会叠成一片),过一会儿再漏会再响。
+8 -2
View File
@@ -180,6 +180,11 @@ and research routes (`{m, s, e, cp:[['MOVE',r,c]…]}`). `spawnsFromTemplate(wav
template into `{ routes, spawns, maxPlayTime, overrides, extraRoutes }` (non-spawn `action` entries are skipped; `unharmful`
and `tag:'part'` spawns don't count in `total`).
A `bounty` pays `coins` once, when the enemy really dies (not a knock-out it survives; a leak pays nothing), to
`Battle._bountyPayee`: the player of the operator or summon that dealt the blow, if that player is in the battle; any
other death (无来源 damage such as 活性源石, its own HP loss, another enemy, an ownerless unit) pays `ownerPlayerId` when
that player is in the battle, else — 联防, where it is the leaker — the helper whose half the enemy fell on (0.2.0).
Leader parts (`tag:'part'`) pass damage to their leader with `loseHp(leader, share, { source, from, sourceless: true })`
(无来源, credited to the attacker's `bossDamage`): `PART_TRANSFER` 1 for 斩胄之剑 / 破胄之锤 (`BLADE_TRANSFER`, the same
constant) and 碎铳之簧 (PRTS "受到伤害时令假想敌:胄/铳受到等量的无来源生命流失"; DESIGN §20.10, §20.13). Content may replace a part mid-battle: every 剑/锤 sortie (content/bosses.js `kitBlade`)
@@ -366,8 +371,9 @@ still standing after `Revive[Trigger].interval` s stands up again with full HP),
instance or a block starts a 2 s change). Each form change goes through `setForm(b, e, form, fxKind, params)`: the
unit keeps it (`e.form`, published as UnitInfo `form`, so a view built mid-battle from `fieldMeta()` — a watched
teammate's field, 联防 observers, a reconnect — starts in it: `render/app/info.js renderInfo` hands it to the view) and the
fx announces it as its `form`: a 'phase' fx (crawl, translator_* — also its `kind`), 'ember' ('husk'), 'revive'
('revived' / 'form2' / 'fly'), 'telegraph' ('reborn') or 'stone' ('stone') — render/units.js FORMS. An operator has one
fx announces it as its `form`: a 'phase' fx (crawl, translator_*, a prisoner's 'warning' — also its `kind`), 'ember'
('husk'), 'revive' ('revived' / 'form2' / 'fly'), 'telegraph' ('reborn'), 'stone' ('stone') or 'liberate' (a prisoner's
'liberty') — render/units.js FORMS. An operator has one
form too: a 傀儡师's <替身> (`professions.js installDollkeeper`: `u.form` 'doll' from the switch to it — fx 'substitute'
`{ form: 'doll', dur }` — until the switch back, fx 'swap' `{ form: null }`, or its knock-out, fx 'dollEnd' `{ form: null }`
after the 'die' event). Barrier / charge
+1 -1
View File
@@ -29,7 +29,7 @@ view.holdPiece(uid, {row,col}|null) // keep a dropped piece on a tile w
view.setPieceDir(uid, dir) // show a prep piece facing UP|RIGHT|DOWN|LEFT (wheel preview / stored dir)
view.resize() ; view.destroy()
```
Visuals: oblique perspective board (tilted ~30°, trapezoid tiles), raised highland blocks with side faces, road/floor/forbidden styles per research 07 §7, pulsing red gates, blue objective, dashed hand pads. Units: Spine (Front/Back rule, feet anchored — flying units hover `FLY_HOVER` 1.3 tiles up, the client's 0.35 in character space, research 12, §25.13.5 —, shadow sprite on the ground), elite gold outline glow, tier chip, HP bar (green ally / red enemy), SP bar (skill ready glow), status icons, the element gauge row under the bars — icon + white bar of the remaining 元素值, element-coloured refill during a 爆发冷却 (§18.3, §20.8); enemies drawn × their official prefab factor (enemies.json `modelScale`, §20.4); an enemy's mode — the `form` of a sim fx (`shared/protocol.js fxForm`), or UnitInfo `form` for a view built later through `render/app/info.js renderInfo` — switches clip sets (`render/units.js FORMS`: 掠海漂移体 crawl, 暴鸰 bombed, 转译基底's forms, the 逐火 embers, the leaders' 重生, 守墓石像; closing clips timed from the fx `dur`), a one-off cast (`PROJ[kind].once`) plays once, and a local-only model's web alias is tinted (`ALIAS_TINT`: 灼热 / 炽焰源石虫, §21.14); damage numbers (phys orange-white, arts purple, true white, heal green); projectiles drawn per kind, hit sparks and melee slashes, skill activation bursts and auras (§17.3); death fade for enemies, summons and devices — a knocked-out operator stays on its tile in its held Die pose under a redeploy ring (§18.3); leak flash at the objective. Fallback when Spine missing/failed: avatar in a rarity-coloured diamond with bob/lunge tweens — a failed or timed-out model is loaded again (bounded), and a view re-resolves its model and avatar when the asset manifest arrives late or the tab is shown again (§21.27). 60 fps target with ≤ 120 units. Picking (which unit a press / hover / dropped item is on) and the drag target follow one rule, `render/pick.js` — the tile under the pointer (§18.1); the Spine store never hands out a skeleton whose unload is in flight (§17.1).
Visuals: oblique perspective board (tilted ~30°, trapezoid tiles), raised highland blocks with side faces, road/floor/forbidden styles per research 07 §7, pulsing red gates, blue objective, dashed hand pads. Units: Spine (Front/Back rule, feet anchored — flying units hover `FLY_HOVER` 1.3 tiles up, the client's 0.35 in character space, research 12, §25.13.5 —, shadow sprite on the ground), elite gold outline glow, tier chip, HP bar (green ally / red enemy), SP bar (skill ready glow), status icons, the element gauge row under the bars — icon + white bar of the remaining 元素值, element-coloured refill during a 爆发冷却 (§18.3, §20.8); enemies drawn × their official prefab factor (enemies.json `modelScale`, §20.4); an enemy's mode — the `form` of a sim fx (`shared/protocol.js fxForm`), or UnitInfo `form` for a view built later through `render/app/info.js renderInfo` — switches clip sets (`render/units.js FORMS`: 掠海漂移体 crawl, 暴鸰 bombed, 转译基底's forms, the 逐火 embers, the leaders' 重生, 守墓石像, the 孤岛风云 prisoners' warning and 解放; closing clips timed from the fx `dur`), a one-off cast (`PROJ[kind].once`) plays once, and a local-only model's web alias is tinted (`ALIAS_TINT`: 灼热 / 炽焰源石虫, §21.14); damage numbers (phys orange-white, arts purple, true white, heal green); projectiles drawn per kind, hit sparks and melee slashes, skill activation bursts and auras (§17.3); death fade for enemies, summons and devices — a knocked-out operator stays on its tile in its held Die pose under a redeploy ring (§18.3); leak flash at the objective. Fallback when Spine missing/failed: avatar in a rarity-coloured diamond with bob/lunge tweens — a failed or timed-out model is loaded again (bounded), and a view re-resolves its model and avatar when the asset manifest arrives late or the tab is shown again (§21.27). 60 fps target with ≤ 120 units. Picking (which unit a press / hover / dropped item is on) and the drag target follow one rule, `render/pick.js` — the tile under the pointer (§18.1); the Spine store never hands out a skeleton whose unload is in flight (§17.1).
---
+88 -4
View File
@@ -24,7 +24,8 @@ what stays [ASSUMED] and the questions left to the owner → §25.10. The closin
settled (泥岩's 闭锁; 忍冬, 深靛, 阿) → §25.11; release packaging and the asset manifest (the 自选 voices, the summons
with no Spine model) → §25.12; round 18 — 拟态物质 at the copy cap (GitHub #207), 华法琳's 7 / 14 (GitHub #175, PR #192),
a merged elite 拉普兰德 as a new one (GitHub #169), the leader pool per player alive (PR #209), the flying lift and two
model quirks (PR #211) → §25.13.
model quirks (PR #211) → §25.13; the community reports of 2026-10-06 (the 孤岛风云 prisoners drawn freed, 忍冬's trigger, a
bounty burned to death by the 活性源石, 枯朽之种 paying a bounty) → §25.14.
Decisions of the owner: 2026-10-04 — the server stays on plain `node:http` + `ws`, no web framework (§25.1);
2026-10-05 — the 补位 plan (§25.3); the 自选编队 rules, the collab operators out of the pool, ISW-A refused (§25.4);
@@ -36,7 +37,8 @@ kept (§25.7.2); 望's placed 棋子 count in her stock, skills that act through
a melee 突袭 member lands where it can block (§25.11); 华法琳's granted trait at the data's 7 / 14, replacing the 12 / 24
lock (§25.13.2); a newly merged elite 拉普兰德 counts as a new 拉普兰德 (§25.13.3); the leader pool = bloodPoint × the players
alive at the fight's start, adopting PR #209 and replacing 「保持固定血量」 (§25.13.4); flying units at 1.3 tiles and the two
model quirks of PR #211 (§25.13.5).
model quirks of PR #211 (§25.13.5); the bounty pays whenever its enemy dies (relayed with the community
reports, §25.14.3).
### 25.1 Refactor and tooling: the big files split, golden results, lint, types, import boundaries (refactor plan; owner's decision of 2026-10-04: no web framework) — `server/http/`, `server/match/match/`, `server/match/player/`, `server/sim/battle/`, `content/enemies/`, `kits/ops/`, `public/js/ui/gameLogic/`, `render/fx/`, `render/app/`, `screens/game/`, `tools/golden.mjs`, `tools/check-imports.mjs`, `eslint.config.js`, `jsconfig.json`
@@ -668,6 +670,7 @@ its tile, §18.1; §25.9.2). Where a 0.1.4 change met 0.2.0 work:
| A newly merged elite 拉普兰德 is a new 拉普兰德: +8 on its first manual refresh of the round (GitHub #169, §25.13.3) | the owner, 2026-10-06 (was [ASSUMED]: the copies' count carried) |
| The leader pool = bloodPoint × the players alive when the fight starts, solo × 1 (PR #209, §25.13.4) | the owner, 2026-10-06 (replaces 「保持固定血量」; config restores it) |
| Flying units hover 1.3 tiles; 帝国炮火先兆者 ×2 drawn 1.263× taller, 木制瑞印 mirrored (PR #211, §25.13.5) | the owner, 2026-10-06 |
| A bounty pays whenever its enemy dies — terrain and other 无来源 deaths included, in 联防 too (§25.14.3) | the owner, 2026-10-06 (relayed with the community reports) |
Settled by the sources in W5V, no longer questions: 泥岩 S3's dormancy is 闭锁 — she lets go and blocks nobody (PRTS,
§25.11.4); 阿 S2 / S3 keep the data's DEFAULT, 忍冬 S2's and 深靛 S1's notes are what the kits do (§25.11.5).
@@ -680,7 +683,8 @@ the moment a 棋子 leaves, a 棋子 over the cap lost, TRP-X's 7th placed 棋
redeployment; 电弧 S2's area = 赛柯's 3-2 range, standing summons only; the official 突袭 landing taken as random among the
legal tiles, ranged members on the old order, the target's own tile counted as a blocking tile; 泥岩's 反制 during 闭锁
not modelled; the English of the remake's own strings; the lite zip without `public/fonts`, the zips' unchanged
package.json (maintainer scripts fail there); the stand-in and operator kit items of the tables above.
package.json (maintainer scripts fail there); the 联防 payee of a bounty death no operator caused — the helper of the half
it fell on (§25.14.3); the stand-in and operator kit items of the tables above.
Left to the owner (none changed in 0.2.0): 淬羽赫默's 丰润羽翼 as 生命回复速度 (the client template, no PRTS note) and 遥's
break heal on the ATK cached at the grant (both kept, §25.11.5); whether a passive counts as 技能就绪 for the whole
@@ -692,7 +696,8 @@ sources: the ally condition for 阿 S2 / S3, 泥岩 S3's 闭锁.
Open polish (no rule): 34 or more of the 38 summons of the 自选 kits have no Spine skeleton in the online sources, so the
field draws them as the avatar placeholder (§25.12); `scripts/make-windows-bundle.mjs` still copies every tracked file
but test/ (it could reuse the package selection); the THIRD-PARTY-NOTICES "In the release bundle" column does not tell
the lite zip (no fonts) apart.
the lite zip (no fonts) apart; the enemy prefabs whose default clips differ from the manifest's roles (猎狗pro, 大鲍勃,
碎骨, “斩胄之剑” / “破胄之锤”, §25.14.1).
### 25.11 The owner's decisions of 2026-10-06 and the items the sources settled (W5V) — `kits/ops/op-wang.js`, `kits/shared/summoner.js summonTriggerArea`, `content/bonds/addon/battle.js raidTile`, `kits/ops/chess_char_4_18-mudrok.js`
@@ -978,3 +983,82 @@ ported PR credits its author there and here.
`test/render/playtest6-enemies.test.js` (exactly the two 先兆者 stretch and 木制瑞印 mirrors; the 1.263 aspect and the bar
height; the mirrored model's opposite x sign). Docs: DATA §9 (`modelScaleY`, `mirrorX`), ASSETS (model size, flying
units), research 00 / 12.
### 25.14 Community reports of 2026-10-06 (W5AA) — `content/enemies/archetypes.js prisoner`, `render/units.js FORMS`, `tools/assets/spine.mjs PREFAB_SPINE_ROLES`, `sim/battle/economy.js _bountyPayee`
The owner collected four community reports on 2026-10-06. Each was reproduced on the 0.2.0 tree with a script (and,
where the report could be older, on the v0.1.2 / v0.1.4 sources), checked against the official data — the battle
prefabs of the local client, ArknightsGameData's buff templates, PRTS — and the earlier decisions. Two were real and are
fixed (W5AA's commits name every golden scenario moved); two were already fixed and are pinned.
#### 25.14.1 「囚徒类敌人出门就是已解放的模型」: the 孤岛风云 prisoners leave the gate confined and change model as they are freed — `content/enemies/archetypes.js prisoner`, `render/units.js FORMS`, `render/fx/kinds.js SILENT_PHASES`, `tools/assets/spine.mjs PREFAB_SPINE_ROLES`
- **Seen**: 普通囚犯 / 老练囚犯 walked out of the gate drawn freed (a red collar light); no prisoner changed its model when
freed (强壮囚犯, 拳师囚犯, 重犯 and 传奇重犯 stayed grey all battle), on the 2D and the 3D board alike.
- **Official**: each prisoner skeleton holds three clip sets whose collar light is grey, blinking orange and red. The
battle prefabs (local client `battle/enm_pfb_6.ab`, read with UnityPy: the Graphic component's anim key → clip table,
the modes' replace pairs, the clip the Spine starts on) draw mode Default — 【禁锢】 — on the grey set and start on it,
mode R on the orange set and mode L — 【解放】 — on the red one. The buff templates (ArknightsGameData
`battle/buff_template_data.json`): `enemy_confinement` starts `confinement.times` charges; `enemy_confinement[atk_cnt]`
spends one ON_BEFORE_ATTACK unless the prisoner has 麻痹 (PRTS 拳师囚犯 「在持有麻痹的情况下,攻击不计数」) and switches to
mode R when one is left; `enemy_liberty_listener[warning]` switches to mode L before the next attack — PRTS
「进行第4次攻击前,切换至解放状态」.
- **Cause**: the client's name-based role resolver gave 普通 / 老练囚犯 their unnumbered clips, which are the red (freed)
set — their grey set is `*3`; FORMS had no prisoner entry and the sim sent no form. The sim also counted on the
'attack' hook, after the damage, so the 4th attack still hit confined.
- **Now**: `prisoner()` counts in the `before` hook (an attack 麻痹 interrupts never reaches it), sets the form
'warning' before attack times − 1 (fx 'phase', drawn silently — the blinking light is the model's) and 'liberty'
before attack times (fx 'liberate', the white blast as before), so that attack already hits with the liberty bonus;
重犯's free-all and 杰斯顿's knock-out switch every freed prisoner too, and UnitInfo `form` gives a view built later the
right set. FORMS maps 'warning' / 'liberty' for the six skeletons (普通 / 老练囚犯 `*2` / unnumbered, 强壮囚犯 `*2` /
`*3`, 拳师囚犯 / 重犯 / 传奇重犯 `*_orange` / `*_red`). `PREFAB_SPINE_ROLES` gives 普通 / 老练囚犯 their grey `*3` set
as the manifest's roles: data/assets.json regenerated (`fetch-assets --offline --add-only`, JSON compare: those two
`anims` and the hash), data/enemies.json too (`build-data --offline`: their `attackAnim.clip` Attack → Attack3, the
same length and strike frame). The 3D board draws the same Pixi views, so both boards follow.
- [ASSUMED]: none (the modes and their timing come from the prefabs and the buff templates).
- Found by the same audit (all 242 enemy prefabs against the manifest's roles), not changed, for later: 猎狗pro moves on
`Run_Loop` (manifest `Move_Loop`), 大鲍勃 attacks on `Attack2`, 碎骨 moves on `Move_02`, “斩胄之剑” / “破胄之锤” idle on
`Idle_A` (a 0 s pose the resolver skips on purpose); 杰斯顿, 扎罗 and 再生 differ only in the death clip their FORMS
already set.
- Golden: 28 scenarios — the warning's 'phase' fx only: roster-001 / 003 / 007 / 024 / 033, bond-miraShip-low; the freed 4th
attack: roster-004 / 021 / 022 / 026, bond-kazimierzShip-low / raidShip-low / soloShip-low / victoriaShip-low /
visiShip-low, standin-01, diy-017 / 024 / 061 / 065 / 066 / 094 / 097 / 104 / 105 / 127, and the bot matches
solo-ABYSS-2, solo-HARD-9-boosted. Tests: `test/content/feedback5-prisoners.test.js`,
`test/render/feedback5-prisoners.test.js`, `test/render/feedback5-prisoners.browser.test.js` (RENDER_E2E=1, both boards).
Docs: docs/ASSETS.md, docs/SIM.md, DESIGN §9 (design/client.md).
#### 25.14.2 「敌人在忍冬技能范围内没有开技能,在攻击范围才开」: already answered by the larger-range rule (§25.5) — no change
- **Checked**: data/chess.json — S1 小施惩戒 DEFAULT (AUTO, no larger range), S2 坠刃拷问 SKILL_RANGE on its 技能范围 3-12
(§25.11.5), S3 隐狐之艺 (her default) ACTIVE_RANGE on its running range 2-2 (`rawRule` DEFAULT); she is in neither
part of data/backups.json. On v0.1.4 S3 was on DEFAULT and cast only with an enemy in her 1-tile range — the report;
on this tree it casts with an enemy two tiles ahead (not three), S2 on any tile of the 3-12.
- Golden: unchanged. Pinned: `test/sim/feedback5-community-pins.test.js`.
#### 25.14.3 「被源石地板烫死的悬赏没给赏金」: a bounty enemy that dies with no operator behind it pays in 联防 too — `sim/battle/economy.js _bountyPayee`, `sim/battle/deploy.js _remove`
- **Seen**: a bounty enemy burned to death by the 活性源石 paid no bounty.
- **Checked**: on its own field it always paid its owner — all 96 walking kill-bounty enemies on 战场#04 with no
operator, on this tree and on v0.1.4: none unpaid. The loss is in 联防: a leaked bounty enemy re-enters carrying
`bounty.ownerPlayerId` = the leaker (unite.js planUnite), and a death without an operator killer fell back to that
owner, who has no per-player entry in the 联防 battle, so `addCoins` dropped the coins. Until 0.1.3 the 联防 field was
the round's map (GitHub #41), so 战场#04's 活性源石 burned leaked bounty enemies for nothing; the 联防 maps have no
terrain now, but a 无来源 tick, the enemy's own HP loss or another enemy's hit still paid nobody.
- **Official**: PRTS 卫戍协议:盟约 决策 「该敌人于对应玩家所属区域倒下时,使相应玩家获得额外资金」 — no exception for 环境伤害;
the owner's decision (relayed 2026-10-06): the bounty pays whenever the body dies.
- **Now**: `_bountyPayee` — an operator or summon of a player in the battle that dealt the blow pays its player (as
before, a 联防 helper included); any other death pays the card's owner when that player fights there (own field, Final
Assault / Hidden Core: unchanged), else the player whose half of the field the enemy fell on (`_ownerForTile`).
- [ASSUMED]: the 联防 payee of a death nobody caused (no source names one; PRTS's 「于…区域倒下」 reads as the area's
player).
- Golden: unchanged. Tests: `test/sim/feedback5-bounty-payee.test.js` (the 联防 cases fail on the parent; the own-field
活性源石 death, a helper's operator on the other half and a pair boss field pinned). Docs: docs/SIM.md §1.2,
docs/META.md, docs/PLAYING.md.
#### 25.14.4 「悬赏敌人枯朽萃聚使徒召唤的枯朽之种被击杀也会获得赏金」: already fixed in 0.1.3 (§23.25) — no change
- **Checked**: the 使徒's BornBugs spawn its seeds through `spawnChildren`, which drops the card's `bountyId` /
`bountyCoins` (§23.25); a seed never had a `bounty` on the own field, so killing one never paid. On the v0.1.2 sources a
bounty 使徒 whose seeds leaked sent every seed into 联防 carrying the card — 15 of 16 re-entries paid it again — which
is the report; on this tree only the 使徒's own leak carries it.
- Golden: unchanged. Pinned: `test/sim/feedback5-community-pins.test.js`.
+3 -2
View File
@@ -97,9 +97,10 @@ const FX_GUESS = [
/**
* 'phase' (an enemy's mode change, render/units.js FORMS) kinds the model shows on its own: 暴鸰 'bombed' — its bomb is
* the 'droneBomb' projectile of the same moment, a puff on the drone would read as something else (feedback D4).
* the 'droneBomb' projectile of the same moment, a puff on the drone would read as something else (feedback D4); a
* prisoner's 'warning' — its collar light starts blinking orange (the official mode R shows nothing else).
*/
const SILENT_PHASES = new Set(['bombed']);
const SILENT_PHASES = new Set(['bombed', 'warning']);
/** Visual spec of an fx kind (see FX_KINDS); `extra.kind` / `extra.element` may pick a better colour. */
export function fxSpec(kind, extra = {}) {
+18
View File
@@ -206,6 +206,11 @@ export const EL_BAR = Object.freeze({ icon: 0.15, min: 8, max: 15, enemy: 0.8, g
* clip (`end`) is timed from the 重生's `dur` (the 'telegraph' fx) to end with it, so the second form walks and
* attacks on its own clips at once (a view that missed the timing — built mid-重生 — skips the closing clip);
* - 守墓石像 (forms 'stone' → 'fly'): the statue on Sleep [ASSUMED by name], then the flyer's *_2 clips.
* - the 孤岛风云 prisoners (sim content/enemies/archetypes.js prisoner: forms 'warning' → 'liberty'), as their official
* battle prefabs' modes: confined on the manifest's clips (the grey collar light: 普通囚犯 / 老练囚犯 Idle3 … through
* tools/assets/spine.mjs PREFAB_SPINE_ROLES, 强壮囚犯 Idle …, 拳师囚犯 / 重犯 / 传奇重犯 *_grey), mode R — the warning
* before the last confined attack — on the blinking orange set (*2, *_orange), mode L — 【解放】 — on the red set
* (普通囚犯 / 老练囚犯 Idle …, 强壮囚犯 *3, the others *_red); no change clip (the prefab switches the set at once).
* - the 傀儡师 operators' <替身> (sim professions.js installDollkeeper: form 'doll' from the start of the switch to it
* until the switch back starts, GitHub issue #44): the skeletons draw it on their *_B clips (their own slots — the
* 本体's are hidden). 归溟幽灵鲨: Start_B fades it in (the 1 s switch), Idle_B (it never attacks), Die_B breaks it
@@ -239,6 +244,13 @@ const STATUE = Object.freeze({
fly: Object.freeze({ change: null, roles: clipSet('Idle_2', 'Move_2', 'Die_2', 'Attack_2') }),
});
const JAKILL2 = clipSet('C2_Idle', 'C2_Move', 'C2_Die', 'C2_Attack');
/** A prisoner's 'warning' (mode R) and 'liberty' (mode L) clip sets: the clip-name suffix of each (see the list above). */
const prisoner = (warn, free) => Object.freeze({
warning: Object.freeze({ change: null, roles: clipSet(`Idle${warn}`, `Move${warn}`, `Die${warn}`, `Attack${warn}`) }),
liberty: Object.freeze({ change: null, roles: clipSet(`Idle${free}`, `Move${free}`, `Die${free}`, `Attack${free}`) }),
});
const PRISONER = prisoner('2', '');
const PRISONER_COLOURED = prisoner('_orange', '_red');
/** A 傀儡师's 替身 roles: idle `idle`, death `die`, attack `attack` (null: none), no skill clip of its own. */
const dollRoles = (idle, die, attack = null) => Object.freeze({
idle, deploy: idle, die, attack: attack ? Object.freeze({ begin: null, loop: attack, end: null }) : null, attackDown: null, skill: null,
@@ -282,6 +294,12 @@ export const FORMS = Object.freeze({
}),
enemy_1172_dugago: STATUE,
enemy_1172_dugago_2: STATUE,
enemy_1116_liprr: PRISONER,
enemy_1116_liprr_2: PRISONER,
enemy_1119_vofsd: prisoner('2', '3'),
enemy_1118_lidbox_2: PRISONER_COLOURED,
enemy_1121_lifbos: PRISONER_COLOURED,
enemy_1121_lifbos_2: PRISONER_COLOURED,
});
/**
+5 -4
View File
@@ -22,10 +22,11 @@
// them beside the operators; one off the field at the end enters fresh [ASSUMED]). Enemies = the union of every leaker's
// counted leaks (same stats: the SpawnSpec mods travel with the leak), routed on the escaped template (`escaped_single`
// for 1 helper, `escaped_multi` for 2): walkers on its `lrsldr` action, flyers on `yokai`, tokens on `gopro_2` /
// `lazerd` (waves.js buildUniteWave); kill bounties keep paying the killer (a helper). No IN_BATTLE layer gains ("该阶段
// 不能叠加层数"); the helpers' bonds carry the layers their own combat reached (PlayerState.battleInput `reached`: the
// round's pending gains, capped like settle() — the strip's count; "以其阵地当前的状态" [ASSUMED] includes them; until 0.1.3
// the round-start layers), and settle() still adds those gains once. Time limit = the round's combat limit.
// `lazerd` (waves.js buildUniteWave); kill bounties keep paying the killer (a helper) — a death no operator caused pays
// the helper whose half it fell on (Battle._bountyPayee). No IN_BATTLE layer gains ("该阶段不能叠加层数"); the helpers'
// bonds carry the layers their own combat reached (PlayerState.battleInput `reached`: the round's pending gains, capped
// like settle() — the strip's count; "以其阵地当前的状态" [ASSUMED] includes them; until 0.1.3 the round-start layers),
// and settle() still adds those gains once. Time limit = the round's combat limit.
// LP: an enemy still alive at the end (leaked in the unite battle, or never spawned before the limit) costs its
// SOURCE player 1 LP; each player's round loss = min(lpCap, survivors attributed to them + leaks that could not
// re-enter) — the same 10 cap as a normal round.
+1 -4
View File
@@ -139,10 +139,7 @@ export class BattleDeploy {
if (pp) pp.killed++;
}
if (killer) killer.stats.kills++;
if (unit.bounty && unit.bounty.coins > 0) {
const payee = killer && killer.side === 'ally' && killer.ownerId != null ? killer.ownerId : (unit.bounty.ownerPlayerId ?? unit.ownerId);
this.addCoins(payee, unit.bounty.coins);
}
if (unit.bounty && unit.bounty.coins > 0) this.addCoins(this._bountyPayee(unit, killer), unit.bounty.coins);
}
}
// the reason ('killed' | 'retreat' | 'expired' | …) lets the client keep the knock-down sound for real knock-outs
+18
View File
@@ -48,6 +48,24 @@ export class BattleEconomy {
return u.side === 'ally' ? [u.tileR, u.tileC] : [Math.round(u.y), Math.round(u.x)];
}
/**
* The player a kill bounty (`unit.bounty`: a 悬赏 card's enemy, a 鸭爵 swap) pays when its enemy dies: the bounty pays
* whenever the body dies (the owner's decision, relayed 2026-10-06). An operator or summon of a player of this battle
* that dealt the blow pays its player ("将其击倒者获得N资金" — a 联防 helper included); any other death — 无来源 damage
* (terrain, an uncredited tick), its own drain, another enemy, an ownerless unit — pays the card's owner when that
* player fights here (own field, Final Assault / Hidden Core), else (联防, where the owner is the leaker) the player
* whose half of the field it fell on: PRTS 卫戍协议:盟约 决策 "该敌人于对应玩家所属区域倒下时,使相应玩家获得额外资金"
* [ASSUMED for 联防: no source names the payee of a death nobody caused there]. Until 0.2.0 that fallback was the
* leaker, who has no entry in a 联防 battle, and addCoins dropped the coins (community report of 2026-10-06
* 「被源石地板烫死的悬赏没给赏金」: until 0.1.3 the 联防 field was the round's map, 战场#04's 活性源石 included).
*/
_bountyPayee(unit, killer = null) {
if (killer && killer.side === 'ally' && killer.ownerId != null && this._pp(killer.ownerId)) return killer.ownerId;
const owner = unit.bounty?.ownerPlayerId ?? unit.ownerId;
if (owner != null && this._pp(owner)) return owner;
return this._ownerForTile([Math.round(unit.y), Math.round(unit.x)]);
}
addCoins(playerId, n) {
const pp = this._pp(playerId);
if (!pp || !(n > 0) || !Number.isFinite(n)) return 0;
+2 -2
View File
@@ -85,8 +85,8 @@
// kind, tiles?, id?, form?} (delayed strikes, charges, 'reborn' with form 'reborn') · 'beam' {from, to, kind} ·
// 'summon' {id, key} · 'ember' {id, hits, dur, form: 'husk'} · 'revive' {id, kind?, form: 'form2' | 'revived' | 'fly'}
// · 'stone' {id, dur, form: 'stone'} · 'blink' {id, fx, fy} · 'charge' {id, tx, ty} · 'expose' {id} · 'shieldBreak'
// {id} · 'liberate' {id} · 'phase' {id, kind, dur?, form?} (form changes — 掠海漂移体 'crawl', 暴鸰 'bombed',
// translator_* — and barrier / charge states) · 'lpLoss' {value, reason} · 'steal' · 'ignite'. Forms go through
// {id} · 'liberate' {id, form: 'liberty'} · 'phase' {id, kind, dur?, form?} (form changes — 掠海漂移体 'crawl', 暴鸰
// 'bombed', translator_*, a prisoner's 'warning' — and barrier / charge states) · 'lpLoss' {value, reason} · 'steal' · 'ignite'. Forms go through
// setForm(): the unit keeps it (`e.form`, UnitInfo `form`) and the fx's `form` is the model's clip set from then on
// (render/app.js → UnitView.setForm, units.js FORMS); the client keeps every fx with a `form` through catch-ups and
// hidden tabs (shared/protocol.js fxForm).
+19 -3
View File
@@ -232,16 +232,28 @@ const selfFear = (ab) => ({
},
});
/** Prisoners (禁锢 → 解放). */
/**
* Prisoners (孤岛风云: 禁锢 → 解放). The official battle prefabs (local client battle/enm_pfb_*.ab) have three modes and the
* buff templates (buff_template_data enemy_confinement, enemy_confinement[atk_cnt], enemy_liberty_listener[warning]) move
* between them: the 禁锢终端 starts with `confinement.times` charges; before each attack (ON_BEFORE_ATTACK — here the
* `before` hook: an attack 麻痹 interrupts never gets there, PRTS 拳师囚犯 "在持有麻痹的情况下,攻击不计数") one is spent, and
* the one that leaves a single charge switches it to mode R, the warning — still confined, its collar light blinking
* orange; before the next attack it switches to mode L, 【解放】, so the times-th attack already hits freed (PRTS
* "进行第4次攻击前,切换至解放状态"; until 0.2.0 it was freed after that attack's damage). The model follows the mode
* (setForm: UnitInfo `form`, render/units.js FORMS): the manifest's clips are the grey confined set, 'warning' the orange
* set, 'liberty' the red one — the 'liberate' fx carries it (a community report of 2026-10-06: they came out of the gate
* drawn freed and never changed).
*/
function prisoner(ab, { freeAll = false } = {}) {
const t = (k) => T(ab, k) ?? 0;
const times = Math.max(1, Math.round(T(ab, 'confinement.times') ?? 4));
const liberate = (b, e, a) => {
if (a.free || !e.alive) return;
a.free = true;
b.removeBuff(e, 'ab:confined');
b.addBuff(e, { key: 'ab:liberty', persist: true, visible: true, mods: {
atkPct: t('liberty.atk'), defIgnorePct: t('liberty.def_penetrate'), resFlat: t('liberty.magic_resistance'), hpRegen: t('liberty.hp_recovery_per_sec') } });
b.fx('liberate', { x: e.x, y: e.y, id: e.id });
setForm(b, e, 'liberty', 'liberate');
if (freeAll && !stOf(b).freedAll) {
// "第一次解放时同时解放全场敌人"
stOf(b).freedAll = true;
@@ -254,7 +266,11 @@ function prisoner(ab, { freeAll = false } = {}) {
a.n = 0; a.free = false;
b.addBuff(e, { key: 'ab:confined', persist: true, visible: true, mods: { aspd: t('confinement.attack_speed'), defFlat: t('confinement.def') } });
},
attack(c, b, e, a) { if (!a.free && ++a.n >= (T(ab, 'confinement.times') ?? 4)) liberate(b, e, a); },
before(c, b, e, a) {
if (a.free) return;
if (++a.n >= times) liberate(b, e, a);
else if (a.n === times - 1) setForm(b, e, 'warning');
},
};
}
+91
View File
@@ -0,0 +1,91 @@
// test/content/feedback5-prisoners.test.js — community report of 2026-10-06 「囚徒类敌人出门就是已解放的模型」: the 孤岛风云
// prisoners (普通 / 老练 / 拳师 / 强壮囚犯, 重犯, 传奇重犯) follow their official battle prefabs' three modes
// (content/enemies/archetypes.js prisoner): confined, mode R — the warning — before the last confined attack (its
// collar light blinks orange: model form 'warning'), mode L — 【解放】 — before the confinement.times-th attack, which
// already hits freed (PRTS "进行第4次攻击前,切换至解放状态"; buff_template_data enemy_confinement[atk_cnt] /
// enemy_liberty_listener[warning]); model form 'liberty' (render/units.js FORMS; test/render/feedback5-prisoners.test.js).
// Until 0.2.0 the sim freed them after the 4th attack's damage and never told the client: they kept the manifest's
// clips, which for 普通囚犯 / 老练囚犯 were the freed set.
// Run: node --test test/content/feedback5-prisoners.test.js
import { test } from 'node:test';
import assert from 'node:assert/strict';
import fs from 'node:fs';
import { makeBattle, chessRec, checkInvariants } from '../helpers/battleHarness.js';
import * as enemiesMod from '../../server/sim/content/enemies.js';
import * as bossesMod from '../../server/sim/content/bosses.js';
import { unitInfo } from '../../server/sim/snapshot.js';
const E = JSON.parse(fs.readFileSync(new URL('../../data/enemies.json', import.meta.url), 'utf8'));
const PRISONERS = ['enemy_1116_liprr', 'enemy_1116_liprr_2', 'enemy_1118_lidbox_2', 'enemy_1119_vofsd', 'enemy_1121_lifbos', 'enemy_1121_lifbos_2'];
const tb = (key, k) => E[key].talents.bb[k];
// a wall that blocks and never attacks, DEF 0: a prisoner's hit lands its ATK exactly
const WALL = chessRec({ id: 't_wall', profession: 'TANK', stats: { atk: 0, maxHp: 1e9, def: 0, res: 0, blockCnt: 3 }, rangeGrid: [[0, 0]], skill: null });
function arena() {
return makeBattle({
content: 'generic', extraContent: [enemiesMod, bossesMod], seed: 7, autoFinish: false, timeLimit: 600,
defs: { chess: { t_wall: WALL } }, kits: { t_wall: () => ({ trait: { noAttack: true } }) },
units: [{ chessId: 't_wall', row: 9, col: 5 }], hooks: ['damaged', 'beforeAttack'], captureNoisy: true,
});
}
const put = (h, key, pos) => h.spawn(key, { pos, routeIndex: 0, mods: { speedMul: 0 } });
const fxOf = (h, id) => h.eventsOf('fx').filter((f) => f[4] && f[4].id === id);
for (const key of PRISONERS) {
test(`${key} ${E[key].name}: the warning before attack ${tb(key, 'confinement.times') - 1}, freed before attack ${tb(key, 'confinement.times')} (its hit already freed), model forms 'warning' → 'liberty'`, () => {
const h = arena();
h.step();
const e = put(h, key, [9, 5]);
const times = tb(key, 'confinement.times');
const base = E[key].stats.atk;
const hits = () => h.hooksOf('damaged').filter((c) => c.source === e && c.dmg.isAttack).map((c) => c.amount);
assert.equal(e.form ?? null, null, 'spawns confined, on the manifest clips');
assert.equal(unitInfo(e).form, undefined);
// the form each attack starts in: read at its beforeAttack (after the kit's own handler, priority 50)
const formAt = [];
h.b.on('beforeAttack', (c) => { if (c.attacker === e) formAt.push(e.form ?? null); }, { priority: -100 });
const aspdAt = [];
h.b.on('attack', (c) => { if (c.attacker === e) aspdAt.push(e.s.aspd); }, { priority: -100 });
assert.ok(h.runUntil(() => e.stats.attacks >= times + 1, 120), 'attacks');
assert.deepEqual(formAt.slice(0, times + 1), [...Array(times - 2).fill(null), 'warning', 'liberty', 'liberty']);
const dealt = hits();
for (let i = 0; i < times - 1; i++) assert.equal(dealt[i], base, `confined hit ${i + 1}`);
assert.ok(Math.abs(dealt[times - 1] - base * (1 + tb(key, 'liberty.atk'))) < 1e-6, `attack ${times} hits freed: ${dealt[times - 1]}`);
// mode R is still confined: the interval after the warning attack is the confined one
assert.equal(aspdAt[times - 2], 100 + tb(key, 'confinement.attack_speed'), 'the warning attack still confined');
assert.equal(aspdAt[times - 1], 100, 'freed from attack ' + times);
const forms = fxOf(h, e.id).filter((f) => f[4] && Object.hasOwn(f[4], 'form')).map((f) => [f[1], f[4].form]);
assert.deepEqual(forms, [['phase', 'warning'], ['liberate', 'liberty']], 'the two mode changes reach the client');
assert.equal(unitInfo(e).form, 'liberty', 'a view built later draws it freed');
checkInvariants(h.b);
assert.equal(h.b.errors.length, 0, JSON.stringify(h.b.errors[0]));
});
}
test('重犯 / 传奇重犯: the first liberation frees every prisoner on the field, each switched to its liberty form', () => {
for (const key of ['enemy_1121_lifbos', 'enemy_1121_lifbos_2']) {
const h = arena();
h.step();
const e = put(h, key, [9, 5]);
const other = put(h, 'enemy_1116_liprr', [11, 8]);
assert.ok(h.runUntil(() => e.form === 'liberty', 120));
assert.equal(other.form, 'liberty', `${key}: the other prisoner is drawn freed`);
assert.ok(!other.findBuff('ab:confined'));
assert.ok(fxOf(h, other.id).some((f) => f[1] === 'liberate' && f[4].form === 'liberty'));
}
});
test('拳师囚犯 (PRTS 天赋 "在持有麻痹的情况下,攻击不计数"): an attack 麻痹 interrupts spends no charge', () => {
const key = 'enemy_1118_lidbox_2';
const h = arena();
h.step();
const e = put(h, key, [9, 5]);
h.b.applyStatus(e, 'palsy', { duration: 60, stacks: 2, source: h.unit('t_wall') });
const palsied = e.findBuff('palsy');
assert.ok(palsied, 'palsy on');
const st = e.mem.ab.list.find((a) => a.liberate);
assert.ok(h.runUntil(() => !e.findBuff('palsy'), 60), 'the stacks were spent on interrupted attacks');
assert.equal(st.n, 0, 'no charge spent');
assert.equal(e.stats.attacks, 0);
});
+48 -48
View File
@@ -507,26 +507,26 @@
"rngDraws": 0,
"errors": {"count":0,"kinds":[]},
"players": {
"p1": {"killed":16,"total":16,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":121696,"bossDmg":0,"heal":12975,"deaths":2,"layerGains":{"kazimierzShip":1}}
"p1": {"killed":16,"total":16,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":121696,"bossDmg":0,"heal":13111,"deaths":2,"layerGains":{"kazimierzShip":1}}
},
"units": [
["p1",1,"op","chess_char_2_18_a",0,null,2218,1,7,8,47014,181,0,23,1],
["p1",2,"op","chess_char_4_23_a",2,null,2179,1,6,0,0,0,0,0,0],
["p1",3,"op","chess_char_4_22_a",2,null,2022,1,8,4,26309,0,0,20,1],
["p1",4,"op","chess_char_1_19_a",1,null,0,0,9,0,15153,4341,0,36,1],
["p1",5,"op","chess_char_2_12_a",1,null,0,0,10,1,24445,7624,3661,58,1],
["p1",6,"op","chess_char_4_21_a",1,null,1271,1,4,0,0,0,5768,34,1],
["p1",5,"op","chess_char_2_12_a",1,null,0,0,10,1,24445,7624,3715,58,1],
["p1",6,"op","chess_char_4_21_a",1,null,1271,1,4,0,0,0,5793,34,1],
["p1",7,"op","chess_char_4_24_a",1,null,1726,1,5,3,8775,0,0,13,2],
["p1",8,"op","chess_char_4_25_a",2,null,378.43,1,11,0,0,4598,3546,0,1],
["p1",8,"op","chess_char_4_25_a",2,null,378.43,1,11,0,0,4733,3603,0,1],
["-","~1","device","trap_1105_accrate",null,null,100,1,1,0,0,0,0,0,null],
["-","~2","device","trap_1105_accrate",null,null,100,1,2,0,0,0,0,0,null],
["-","~3","device","trap_1105_accrate",null,null,100,1,3,0,0,0,0,0,null]
],
"enemies": {"enemy_1116_liprr":[11,11,0,4860,69696],"enemy_1116_liprr_2":[4,4,0,89,34560],"enemy_1121_lifbos":[1,1,0,7831,23040]},
"hooks": [1,27,2084,238,238,381,381,1709,18,18,8,7,0,7480,13,18,16,0,1,18,1,0,0],
"events": {"atk":263,"deploy":8,"die":18,"dmg":373,"engage":5,"fx":58,"heal":49,"layer":1,"skill":15,"spawn":27,"status":49},
"fx": {"displace":16,"garrison":1,"healField":1,"liberate":3,"redistribute":15,"reweave":1,"sandChains":2,"shield":1,"slash":17,"truesilver":1},
"snaps": "86cad855 f20e9695 8c83ae10 b279680f d6a08407 cca87c8f d3dc995b"
"enemies": {"enemy_1116_liprr":[11,11,0,4995,69696],"enemy_1116_liprr_2":[4,4,0,89,34560],"enemy_1121_lifbos":[1,1,0,7831,23040]},
"hooks": [1,27,2084,238,238,381,381,1730,18,18,8,7,0,7480,13,18,16,0,1,18,1,0,0],
"events": {"atk":263,"deploy":8,"die":18,"dmg":373,"engage":5,"fx":60,"heal":49,"layer":1,"skill":15,"spawn":27,"status":49},
"fx": {"displace":16,"garrison":1,"healField":1,"liberate":3,"phase":2,"redistribute":15,"reweave":1,"sandChains":2,"shield":1,"slash":17,"truesilver":1},
"snaps": "86cad855 f20e9695 1939f464 021173dc 58cc5398 439c2028 813a103c"
},
"bond-kazimierzShip-high": {
"about": "卡西米尔 high: tier 2 layers 999; chess_char_2_18_b chess_char_3_12_b chess_char_5_08_b chess_char_4_19_b chess_char_1_19_b chess_char_2_12_b chess_char_3_17_b chess_char_5_10_b",
@@ -831,8 +831,8 @@
],
"enemies": {"enemy_1116_liprr":[11,11,0,1485,69696],"enemy_1116_liprr_2":[4,4,0,516,34560],"enemy_1118_lidbox_2":[2,2,0,965,21888]},
"hooks": [1,25,1585,159,159,347,347,0,17,17,7,6,0,4895,8,11,17,0,1,17,0,0,0],
"events": {"atk":200,"deploy":8,"die":17,"dmg":346,"engage":5,"fx":22,"skill":13,"spawn":25,"status":67},
"fx": {"buff":1,"displace":10,"ripple":5,"shield":2,"shieldBreak":1,"volley":3},
"events": {"atk":200,"deploy":8,"die":17,"dmg":346,"engage":5,"fx":23,"skill":13,"spawn":25,"status":67},
"fx": {"buff":1,"displace":10,"phase":1,"ripple":5,"shield":2,"shieldBreak":1,"volley":3},
"snaps": "303551a0 687b75a4 7027e8c4 e095a664 6ecd9ebc f8381df0"
},
"bond-miraShip-high": {
@@ -992,7 +992,7 @@
["p1",1,"op","chess_char_4_17_a",1,null,2849,1,3,0,0,0,0,0,0],
["p1",2,"op","chess_char_4_18_a",1,null,4573.65,1,5,2,16944,46,33,15,2],
["p1",3,"op","chess_char_2_09_a",1,null,2047.24,1,17,3,21927,0,0,26,1],
["p1",4,"op","chess_char_4_19_a",2,null,1354.82,1,9,1,20722,205,0,27,1],
["p1",4,"op","chess_char_4_19_a",2,null,1274.82,1,9,1,20722,285,0,27,1],
["p1",5,"op","chess_char_1_18_a",1,null,3101.37,1,14,5,40597,4523,2400,48,3],
["p1",6,"op","chess_char_4_13_a",1,null,1587,1,4,1,9843,0,0,15,4],
["p1",7,"op","chess_char_4_14_a",1,null,1276,1,6,0,0,0,0,0,0],
@@ -1000,11 +1000,11 @@
["-","~1","device","trap_1105_accrate",null,null,100,1,1,0,0,0,0,0,null],
["-","~2","device","trap_1105_accrate",null,null,100,1,2,0,0,0,0,0,null]
],
"enemies": {"enemy_1116_liprr":[11,11,0,149,69696],"enemy_1116_liprr_2":[4,4,0,812,34560],"enemy_1118_lidbox_2":[2,2,0,19,21888]},
"enemies": {"enemy_1116_liprr":[11,11,0,229,69696],"enemy_1116_liprr_2":[4,4,0,812,34560],"enemy_1118_lidbox_2":[2,2,0,19,21888]},
"hooks": [1,30,1609,188,188,223,219,80,17,20,11,11,0,4826,251,18,17,0,1,17,2,0,7],
"events": {"atk":202,"deploy":11,"die":20,"dmg":205,"engage":6,"fx":36,"heal":49,"layer":2,"skill":24,"spawn":27,"status":68},
"fx": {"aoe":3,"blink":3,"dodge":7,"flame":1,"frostNova":4,"garrison":2,"garrisonGrant":1,"liberate":2,"riposte":7,"rockslide":2,"shieldBreak":4},
"snaps": "0d70c7b9 c3f43a03 eb2f3dd4 ab905094 237a3802 57486e54"
"events": {"atk":202,"deploy":11,"die":20,"dmg":205,"engage":6,"fx":47,"heal":49,"layer":2,"skill":24,"spawn":27,"status":68},
"fx": {"aoe":3,"blink":3,"dodge":7,"flame":1,"frostNova":4,"garrison":2,"garrisonGrant":1,"liberate":2,"phase":11,"riposte":7,"rockslide":2,"shieldBreak":4},
"snaps": "0d70c7b9 c3f43a03 eb2f3dd4 ab905094 8c230eb4 44f76984"
},
"bond-raidShip-high": {
"about": "突袭 high: tier 1 layers 999; chess_char_4_17_b chess_char_4_18_b chess_char_2_09_b chess_char_4_19_b chess_char_1_18_b chess_char_4_14_b chess_char_4_20_b chess_char_4_21_b",
@@ -1274,8 +1274,8 @@
"round": 5,
"seed": 2364080280,
"waveId": "act1autochess_05",
"time": 49.93,
"ticks": 1498,
"time": 52.87,
"ticks": 1586,
"reason": "cleared",
"killed": 17,
"total": 17,
@@ -1293,29 +1293,29 @@
"coins": 0,
"dmg": 126144,
"bossDmg": 0,
"heal": 0,
"heal": 222,
"deaths": 2,
"layerGains": {"lateranoShip":1,"siracusaShip":6}
}
},
"units": [
["p1",1,"op","chess_char_3_16_a",1,null,2716.25,1,3,0,0,0,0,0,0],
["p1",2,"op","chess_char_4_01_a",2,null,0,0,5,2,12361,4221,0,16,1],
["p1",1,"op","chess_char_3_16_a",1,null,1895.28,1,3,0,16,861,40,1,1],
["p1",2,"op","chess_char_4_01_a",2,null,0,0,5,2,11758,4221,0,15,1],
["p1",3,"op","chess_char_1_08_a",1,null,0,0,6,0,3876,2377,0,11,1],
["p1",4,"op","chess_char_3_18_a",2,null,924.43,1,10,7,47345,927,0,49,2],
["p1",4,"op","chess_char_3_18_a",2,null,739.25,1,10,7,47345,1295,183,49,2],
["p1",5,"op","chess_char_3_19_a",2,null,1798.75,1,7,3,11486,0,0,25,1],
["p1",6,"op","chess_char_3_20_a",1,null,1401.25,1,9,0,1027,0,0,9,1],
["p1",7,"op","chess_char_3_21_a",2,null,1705,1,11,1,17937,0,0,26,1],
["p1",8,"op","chess_char_4_02_a",2,null,1785,1,4,3,30882,0,0,8,1],
["p1",8,"op","chess_char_4_02_a",2,null,1785,1,4,3,31470,0,0,9,1],
["p1",9,"token","token_10028_vigil_wolf",null,null,852.9,1,8,1,1229,27,0,3,null],
["-","~1","device","trap_1105_accrate",null,null,100,1,1,0,0,0,0,0,null],
["-","~2","device","trap_1105_accrate",null,null,100,1,2,0,0,0,0,0,null]
],
"enemies": {"enemy_1116_liprr":[11,11,0,68,69696],"enemy_1116_liprr_2":[4,4,0,886,34560],"enemy_1118_lidbox_2":[2,2,0,6598,21888]},
"hooks": [1,28,1498,188,188,328,328,0,19,19,8,5,8,6842,40,21,17,0,1,25,4,0,0],
"events": {"atk":236,"deploy":9,"die":19,"dmg":324,"engage":8,"fx":43,"layer":4,"skill":13,"spawn":28,"status":116},
"fx": {"aoe":1,"camouflage":1,"counter":8,"displace":14,"dp":3,"garrison":4,"liberate":4,"ripple":4,"sermon":1,"shield":2,"wolfShadow":1},
"snaps": "d8f99986 287fd6f2 d2481758 e00d8e59 1fbeb62a"
"enemies": {"enemy_1116_liprr":[11,11,0,81,69696],"enemy_1116_liprr_2":[4,4,0,1254,34560],"enemy_1118_lidbox_2":[2,2,0,7445,21888]},
"hooks": [1,28,1586,190,190,330,330,96,19,19,9,6,7,6989,40,22,17,0,1,25,4,0,0],
"events": {"atk":238,"deploy":9,"die":19,"dmg":328,"engage":9,"fx":49,"layer":4,"skill":15,"spawn":28,"status":116},
"fx": {"aoe":1,"camouflage":1,"counter":7,"displace":15,"dp":4,"garrison":4,"liberate":4,"phase":4,"ripple":5,"sermon":1,"shield":2,"wolfShadow":1},
"snaps": "d8f99986 287fd6f2 d2481758 42051775 65187a04 3a674d02"
},
"bond-soloShip-high": {
"about": "独行 high: tier 1 layers 999; chess_char_5_19_b chess_char_1_08_b chess_char_5_13_b chess_char_5_14_b chess_char_5_17_b chess_char_5_12_b chess_char_5_15_b chess_char_5_20_b",
@@ -1602,15 +1602,15 @@
"bossHpLeft": null,
"rngDraws": 6,
"errors": {"count":0,"kinds":[]},
"players": {"p1":{"killed":17,"total":17,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":122744,"bossDmg":0,"heal":6073,"deaths":1,"layerGains":{}}},
"players": {"p1":{"killed":17,"total":17,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":122744,"bossDmg":0,"heal":6698,"deaths":1,"layerGains":{}}},
"units": [
["p1",1,"op","chess_char_3_06_a",1,null,651.13,1,6,4,23398,6256,0,17,1],
["p1",2,"op","chess_char_3_02_a",1,null,0,0,7,5,35248,3065,0,25,1],
["p1",1,"op","chess_char_3_06_a",1,null,644.35,1,6,4,23398,6263,0,17,1],
["p1",2,"op","chess_char_3_02_a",1,null,0,0,7,5,35248,3209,0,25,1],
["p1",3,"op","chess_char_3_03_a",1,null,1378,1,5,0,0,0,0,0,0],
["p1",4,"op","chess_char_3_04_a",1,null,1864,1,8,1,21821,0,0,0,0],
["p1",5,"op","chess_char_3_05_a",2,null,5435.3,1,9,5,20785,1251,0,21,1],
["p1",6,"op","chess_char_1_06_a",1,null,1137,1,3,2,17074,0,2221,36,1],
["p1",7,"op","chess_char_2_05_a",1,null,1411.2,1,4,0,0,0,3852,22,1],
["p1",5,"op","chess_char_3_05_a",2,null,5435.3,1,9,5,20785,1731,0,21,1],
["p1",6,"op","chess_char_1_06_a",1,null,1137,1,3,2,17074,0,2701,36,1],
["p1",7,"op","chess_char_2_05_a",1,null,1411.2,1,4,0,0,0,3996,22,1],
["p1",8,"op","chess_char_2_10_a",1,null,1078,1,10,0,4419,0,0,29,1],
["-","~1","device","trap_1105_accrate",null,null,100,1,1,0,0,0,0,0,null],
["-","~2","device","trap_1105_accrate",null,null,100,1,2,0,0,0,0,0,null],
@@ -1632,11 +1632,11 @@
["p1","~16","token","token_10031_swire2_gdtrap",null,null,1000,0,43,0,0,0,0,0,null],
["p1","~17","token","token_10031_swire2_gdtrap",null,null,1000,1,44,0,0,0,0,0,null]
],
"enemies": {"enemy_1116_liprr":[11,11,0,305,69696],"enemy_1116_liprr_2":[4,4,0,429,34560],"enemy_1118_lidbox_2":[2,2,0,9839,21888]},
"enemies": {"enemy_1116_liprr":[11,11,0,312,69696],"enemy_1116_liprr_2":[4,4,0,429,34560],"enemy_1118_lidbox_2":[2,2,0,10463,21888]},
"hooks": [1,44,1992,210,210,367,394,51,18,34,6,3,0,6986,15,16,17,0,1,18,0,1,0],
"events": {"atk":210,"deploy":25,"die":34,"dmg":394,"engage":5,"fx":114,"heal":41,"skill":11,"spawn":44,"status":48},
"fx": {"aoe":10,"burst":1,"coin":20,"counter":5,"explode":16,"liberate":3,"overload":1,"strike":40,"summon":17,"taunt":1},
"snaps": "3a6154e2 8441cbea 22a9f920 52b9435f e140955f 6872523a d4e792aa"
"events": {"atk":210,"deploy":25,"die":34,"dmg":394,"engage":5,"fx":123,"heal":42,"skill":11,"spawn":44,"status":48},
"fx": {"aoe":10,"burst":1,"coin":20,"counter":5,"explode":16,"liberate":3,"overload":1,"phase":9,"strike":40,"summon":17,"taunt":1},
"snaps": "3a6154e2 8441cbea 22a9f920 52b9435f e1527c0b db3d00cc 19eea9b6"
},
"bond-victoriaShip-high": {
"about": "维多利亚 high: tier 2 layers 999; chess_char_4_11_b chess_char_4_07_b chess_char_1_06_b chess_char_2_05_b chess_char_2_10_b chess_char_3_08_b chess_char_4_13_b chess_char_4_14_b token_10041_cathy_catsld token_10041_cathy_catsld",
@@ -1696,23 +1696,23 @@
"bossHpLeft": null,
"rngDraws": 37,
"errors": {"count":0,"kinds":[]},
"players": {"p1":{"killed":16,"total":17,"perfect":false,"leaks":1,"leaksUncounted":0,"coins":0,"dmg":97912,"bossDmg":0,"heal":4237,"deaths":2,"layerGains":{}}},
"players": {"p1":{"killed":16,"total":17,"perfect":false,"leaks":1,"leaksUncounted":0,"coins":0,"dmg":97912,"bossDmg":0,"heal":4635,"deaths":2,"layerGains":{}}},
"units": [
["p1",1,"op","chess_char_3_12_a",2,null,0,0,3,0,141,2334,0,7,1],
["p1",2,"op","chess_char_3_03_a",1,null,1378,1,6,0,0,0,0,0,0],
["p1",3,"op","chess_char_2_02_a",1,null,1400,1,1,0,0,0,2973,13,2],
["p1",4,"op","chess_char_3_08_a",1,null,1594,1,4,2,20987,306,0,8,1],
["p1",3,"op","chess_char_2_02_a",1,null,1400,1,1,0,0,0,3263,14,2],
["p1",4,"op","chess_char_3_08_a",1,null,1594,1,4,2,20987,596,0,8,1],
["p1",5,"op","chess_char_3_09_a",1,null,1267,1,5,4,23257,727,0,26,1],
["p1",6,"op","chess_char_3_10_a",1,null,0,0,2,2,9187,2704,0,10,1],
["p1",7,"op","chess_char_3_11_a",1,null,1316,1,7,5,33004,886,0,25,3],
["p1",8,"op","chess_char_3_13_a",1,null,1064,1,8,3,11336,1264,0,37,7],
["p1",9,"token","token_10000_silent_healrb",null,null,1000,1,29,0,0,0,1264,17,null]
["p1",8,"op","chess_char_3_13_a",1,null,1064,1,8,3,11336,1372,0,37,7],
["p1",9,"token","token_10000_silent_healrb",null,null,1000,1,29,0,0,0,1372,18,null]
],
"enemies": {"enemy_1116_liprr":[11,11,0,2113,54450],"enemy_1116_liprr_2":[4,4,0,932,27000],"enemy_1118_lidbox_2":[2,1,1,5176,16462]},
"hooks": [1,28,1790,189,189,208,208,30,18,21,16,16,0,8079,3,27,17,1,1,18,0,0,0],
"events": {"atk":224,"deploy":11,"die":20,"dmg":208,"engage":6,"fx":50,"heal":30,"leak":1,"skill":32,"spawn":26,"status":26},
"fx": {"aoe":1,"displace":19,"liberate":3,"pull":19,"strike":3,"summon":2,"volley":3},
"snaps": "4f49e250 3e34819c 91d6de66 bbe9100a c8c27e86 41a14152"
"enemies": {"enemy_1116_liprr":[11,11,0,2221,54450],"enemy_1116_liprr_2":[4,4,0,932,27000],"enemy_1118_lidbox_2":[2,1,1,5466,16462]},
"hooks": [1,28,1790,191,191,208,208,32,18,21,16,16,0,8079,3,27,17,1,1,18,0,0,0],
"events": {"atk":226,"deploy":11,"die":20,"dmg":208,"engage":6,"fx":54,"heal":32,"leak":1,"skill":32,"spawn":26,"status":26},
"fx": {"aoe":1,"displace":19,"liberate":3,"phase":4,"pull":19,"strike":3,"summon":2,"volley":3},
"snaps": "4f49e250 3e34819c 91d6de66 5985f2e5 1e121271 ece611fe"
},
"bond-visiShip-high": {
"about": "远见 high: tier 1 layers 999; chess_char_4_17_b chess_char_4_18_b chess_char_3_03_b chess_char_4_19_b chess_char_4_16_b chess_char_2_02_b chess_char_4_20_b chess_char_4_21_b token_10000_silent_healrb",
+172 -177
View File
@@ -694,9 +694,9 @@
],
"enemies": {"enemy_1116_liprr_2":[27,15,12,2376,117636],"enemy_1119_vofsd":[48,24,24,8707,332697],"enemy_1121_lifbos_2":[30,13,17,19533,450721]},
"hooks": [1,127,6489,605,605,1107,1107,384,72,125,60,60,0,20482,7,55,105,53,1,72,0,0,0],
"events": {"atk":754,"deploy":22,"die":72,"dmg":1107,"engage":12,"fx":58,"leak":53,"skill":120,"spawn":117,"status":142},
"fx": {"explosion":45,"liberate":13},
"snaps": "05487499 a8b18e74 fcd8134e 4438b830 39d3448d 156fcde5 30992bd5 61b69e44 d6fb8f6e 30401b21 da8006cc 5fd0ccc1 17f85d47 8dd68f64 97fbf0cc 3f50a5d3 b493e556 f378de07 01495b56 97c7741a 506dfe12 5074f15a"
"events": {"atk":754,"deploy":22,"die":72,"dmg":1107,"engage":12,"fx":65,"leak":53,"skill":120,"spawn":117,"status":142},
"fx": {"explosion":45,"liberate":13,"phase":7},
"snaps": "05487499 a8b18e74 fcd8134e 4438b830 39d3448d 156fcde5 30992bd5 61b69e44 d6fb8f6e 30401b21 da8006cc 6c478354 54c2ce56 1e2d36b5 cb92a235 11fbf942 59f10f7b 1ca76e62 372c280f 660e22bb f40cd157 59ca59a3"
},
"diy-018": {
"about": "5_diy1_b=cerber/S1/002_cerber 5_diy2_b=cerber/S2/002_cerber 5_diy1_b=cerber/S3/002_cerber 5_diy2_b=cerber/S1/003_cerber 5_diy1_b=cerber/S2/003_cerber 5_diy2_b=cerber/S3/003_cerber 6_diy1_a=cerber/S1 6_diy2_a=cerber/S2 6_diy1_a=cerber/S3 6_diy2_b=cerber/S1 6_diy1_b=cerber/S2 6_diy2_b=cerber/S3",
@@ -953,35 +953,35 @@
"round": 12,
"seed": 762369271,
"waveId": "act1autochess_h05",
"time": 211.93,
"ticks": 6358,
"time": 212.07,
"ticks": 6362,
"reason": "cleared",
"killed": 15,
"total": 90,
"unspawned": 0,
"bossHpLeft": null,
"rngDraws": 296,
"rngDraws": 297,
"errors": {"count":0,"kinds":[]},
"players": {"p1":{"killed":15,"total":90,"perfect":false,"leaks":75,"leaksUncounted":0,"coins":0,"dmg":636028,"bossDmg":0,"heal":0,"deaths":15,"layerGains":{}}},
"players": {"p1":{"killed":15,"total":90,"perfect":false,"leaks":75,"leaksUncounted":0,"coins":0,"dmg":632369,"bossDmg":0,"heal":0,"deaths":15,"layerGains":{}}},
"units": [
["p1",1,"op","chess_char_5_diy1_a",0,null,1310,1,4,3,63384,0,0,92,3],
["p1",1,"op","chess_char_5_diy1_a",0,null,1310,1,4,1,64453,0,0,92,3],
["p1",2,"op","chess_char_5_diy2_a",1,null,1310,1,7,1,105472,0,0,80,2],
["p1",3,"op","chess_char_5_diy1_a",2,null,1310,1,5,4,109452,0,0,62,3],
["p1",3,"op","chess_char_5_diy1_a",2,null,1310,1,5,6,112971,0,0,62,3],
["p1",4,"op","chess_char_5_diy2_b",0,"none",1570,1,8,0,83094,0,0,94,3],
["p1",5,"op","chess_char_5_diy1_b",1,"none",0,0,89,1,25968,3140,0,22,1],
["p1",6,"op","chess_char_5_diy2_b",2,"none",0,0,103,1,63141,3140,0,21,1],
["p1",7,"op","chess_char_5_diy1_b",0,"uniequip_002_typhon",0,0,80,0,12053,3380,0,11,1],
["p1",8,"op","chess_char_5_diy2_b",1,"uniequip_002_typhon",1690,1,111,1,37291,3380,0,23,1],
["p1",9,"op","chess_char_5_diy1_b",2,"uniequip_002_typhon",0,0,70,0,36233,3380,0,15,1],
["p1",7,"op","chess_char_5_diy1_b",0,"uniequip_002_typhon",1690,1,111,0,6221,3380,0,6,1],
["p1",8,"op","chess_char_5_diy2_b",1,"uniequip_002_typhon",0,0,75,1,36509,3380,0,22,1],
["p1",9,"op","chess_char_5_diy1_b",2,"uniequip_002_typhon",0,0,70,0,34599,3380,0,13,1],
["p1",10,"op","chess_char_5_diy2_b",0,"uniequip_003_typhon",1570,1,110,0,12323,3140,0,15,0],
["p1",11,"op","chess_char_5_diy1_b",1,"uniequip_003_typhon",0,0,2,3,37517,1570,0,25,1],
["p1",12,"op","chess_char_5_diy2_b",2,"uniequip_003_typhon",0,0,76,1,50101,3140,0,20,1]
],
"enemies": {"enemy_1116_liprr_2":[27,4,23,3260,83784],"enemy_1119_vofsd":[39,7,32,16713,212848],"enemy_1121_lifbos_2":[24,4,20,4297,339396]},
"hooks": [1,111,6358,525,525,707,707,3265,30,105,18,14,37,22549,340,18,90,75,1,30,0,0,0],
"events": {"atk":605,"deploy":21,"die":30,"dmg":707,"engage":12,"fx":65,"leak":75,"skill":32,"spawn":102,"status":585},
"fx": {"arrowRain":37,"liberate":22,"mark":6},
"snaps": "f663dadd 739cfa28 d92421df b903d26e 5c5f852f 6d67c2d5 52e8842c 59de4a2e 7d60769f 2030b009 035e1681 167ee574 53f64f1c e495095b 4c1fe515 6d458440 39846d3b 9de0a3ba 5cd0483d f821c3d3 3153e74e c2803a2e"
"enemies": {"enemy_1116_liprr_2":[27,4,23,1570,84329],"enemy_1119_vofsd":[39,7,32,18403,208644],"enemy_1121_lifbos_2":[24,4,20,4297,339396]},
"hooks": [1,111,6362,513,513,696,696,3319,30,105,18,14,37,22039,343,18,90,75,1,30,0,0,0],
"events": {"atk":593,"deploy":21,"die":30,"dmg":696,"engage":12,"fx":71,"leak":75,"skill":32,"spawn":102,"status":592},
"fx": {"arrowRain":37,"liberate":21,"mark":6,"phase":7},
"snaps": "f663dadd 27e67fb5 70c4dbe0 2f7fd391 a62efa10 2f4204be 63184657 599acbe1 17368dc4 8ee2f792 7c264176 a4233ba8 e350e4a1 829caee5 ddc711f6 99242447 05714d7e 703c5346 a3763409 0dc461be f9c40013 9c8b6583"
},
"diy-025": {
"about": "5_diy1_b=typhon/S1/004_typhon 5_diy2_b=typhon/S2/004_typhon 5_diy1_b=typhon/S3/004_typhon 6_diy1_a=typhon/S1 6_diy2_a=typhon/S2 6_diy1_a=typhon/S3 6_diy2_b=typhon/S1 6_diy1_b=typhon/S2 6_diy2_b=typhon/S3 6_diy1_b=typhon/S1/002_typhon 6_diy2_b=typhon/S2/002_typhon 6_diy1_b=typhon/S3/002_typhon",
@@ -2477,32 +2477,32 @@
"time": 216.3,
"ticks": 6489,
"reason": "cleared",
"killed": 5,
"killed": 4,
"total": 105,
"unspawned": 0,
"bossHpLeft": null,
"rngDraws": 60,
"rngDraws": 55,
"errors": {"count":0,"kinds":[]},
"players": {"p1":{"killed":5,"total":105,"perfect":false,"leaks":100,"leaksUncounted":0,"coins":0,"dmg":242310,"bossDmg":0,"heal":24994,"deaths":22,"layerGains":{}}},
"players": {"p1":{"killed":4,"total":105,"perfect":false,"leaks":101,"leaksUncounted":0,"coins":0,"dmg":229072,"bossDmg":0,"heal":23888,"deaths":22,"layerGains":{}}},
"units": [
["p1",1,"op","chess_char_6_diy1_a",0,null,0,0,129,0,8324,5649,280,12,2],
["p1",2,"op","chess_char_6_diy2_a",1,null,1413,1,7,0,0,0,0,0,0],
["p1",3,"op","chess_char_6_diy1_a",2,null,1413,1,9,0,0,0,0,0,0],
["p1",4,"op","chess_char_6_diy2_b",0,"none",0,0,115,0,4357,6974,1440,34,7],
["p1",5,"op","chess_char_6_diy1_b",1,"none",1778,1,130,0,20318,8199,1265,37,1],
["p1",6,"op","chess_char_6_diy2_b",2,"none",0,0,75,0,18493,6221,1920,27,1],
["p1",4,"op","chess_char_6_diy2_b",0,"none",0,0,115,0,5235,7014,1360,32,7],
["p1",5,"op","chess_char_6_diy1_b",1,"none",1778,1,130,0,18542,8239,1185,35,1],
["p1",6,"op","chess_char_6_diy2_b",2,"none",0,0,75,0,18043,6021,1800,24,1],
["p1",7,"op","chess_char_6_diy1_b",0,"uniequip_002_pallas",0,0,72,0,12088,6056,1480,33,8],
["p1",8,"op","chess_char_6_diy2_b",1,"uniequip_002_pallas",0,0,122,0,14748,6924,840,26,1],
["p1",9,"op","chess_char_6_diy1_b",2,"uniequip_002_pallas",0,0,85,3,87377,9523,2717,39,1],
["p1",10,"op","chess_char_6_diy2_b",0,"uniequip_003_pallas",0,0,92,0,8292,3556,80,12,2],
["p1",11,"op","chess_char_6_diy1_b",1,"uniequip_003_pallas",0,0,107,0,20299,5756,5280,44,2],
["p1",12,"op","chess_char_6_diy2_b",2,"uniequip_003_pallas",0,0,5,2,48014,5625,9691,20,1]
["p1",8,"op","chess_char_6_diy2_b",1,"uniequip_002_pallas",0,0,122,0,14748,6964,880,26,1],
["p1",9,"op","chess_char_6_diy1_b",2,"uniequip_002_pallas",0,0,92,3,82764,9339,2837,43,1],
["p1",10,"op","chess_char_6_diy2_b",0,"uniequip_003_pallas",0,0,107,0,10369,6361,3125,31,7],
["p1",11,"op","chess_char_6_diy1_b",1,"uniequip_003_pallas",0,0,3,0,17236,1778,2440,20,1],
["p1",12,"op","chess_char_6_diy2_b",2,"uniequip_003_pallas",0,0,83,1,41724,5956,8500,23,1]
],
"enemies": {"enemy_1116_liprr_2":[27,4,23,6562,94249],"enemy_1119_vofsd":[48,1,47,25200,102950],"enemy_1121_lifbos_2":[30,0,30,32723,45111]},
"hooks": [1,130,6489,395,395,516,516,4394,27,127,26,26,0,7417,46,50,105,100,1,27,0,0,0],
"events": {"atk":497,"deploy":25,"die":27,"dmg":516,"engage":10,"fx":24,"heal":582,"leak":100,"skill":52,"spawn":117,"status":253},
"fx": {"liberate":24},
"snaps": "ae00584b 7e984234 04da3369 e8268eb6 352ee94e 6a8ff4a4 14cc9cf3 aed560d3 5ae43b1e 70a11656 477ecbe2 234d7bd7 fa381bd7 a7e6f273 139bfb73 48507e2d 87f87359 24c47e90 ddfdaba1 ee2458b8 e059ebe8 8d10edda"
"enemies": {"enemy_1116_liprr_2":[27,4,23,7997,94249],"enemy_1119_vofsd":[48,0,48,23934,98913],"enemy_1121_lifbos_2":[30,0,30,31448,35910]},
"hooks": [1,130,6489,385,385,500,500,4414,26,127,30,30,0,7120,44,48,105,101,1,26,0,0,0],
"events": {"atk":476,"deploy":25,"die":26,"dmg":500,"engage":10,"fx":42,"heal":558,"leak":101,"skill":60,"spawn":117,"status":247},
"fx": {"liberate":23,"phase":19},
"snaps": "ae00584b 7e984234 90d5493f 63ce7fd8 16d43b92 44667ff2 569ee0c8 4fc5c14d 62ea59b9 5fcb90b9 b94c5868 b539318a 03dd4a62 6b144703 24713dc5 3fa5f2a5 2fbb9e37 04a09678 13e0b067 901d6fe4 15b0e71b 3f5de694"
},
"diy-062": {
"about": "5_diy1_a=lessng/S1 5_diy2_a=lessng/S2 5_diy1_a=lessng/S3 5_diy2_b=lessng/S1 5_diy1_b=lessng/S2 5_diy2_b=lessng/S3 5_diy1_b=lessng/S1/002_lessng 5_diy2_b=lessng/S2/002_lessng 5_diy1_b=lessng/S3/002_lessng 5_diy2_b=lessng/S1/003_lessng 5_diy1_b=lessng/S2/003_lessng 5_diy2_b=lessng/S3/003_lessng",
@@ -2640,29 +2640,29 @@
"round": 13,
"seed": 1168351812,
"waveId": "act1autochess_h06",
"time": 211.1,
"ticks": 6333,
"time": 207.3,
"ticks": 6219,
"reason": "cleared",
"killed": 81,
"total": 105,
"unspawned": 0,
"bossHpLeft": null,
"rngDraws": 198,
"rngDraws": 192,
"errors": {"count":0,"kinds":[]},
"players": {"p1":{"killed":81,"total":105,"perfect":false,"leaks":24,"leaksUncounted":0,"coins":0,"dmg":1192110,"bossDmg":0,"heal":0,"deaths":6,"layerGains":{}}},
"players": {"p1":{"killed":81,"total":105,"perfect":false,"leaks":24,"leaksUncounted":0,"coins":0,"dmg":1186974,"bossDmg":0,"heal":0,"deaths":6,"layerGains":{}}},
"units": [
["p1",1,"op","chess_char_6_diy1_b",0,"none",2466,1,180,1,13215,2466,0,36,7],
["p1",2,"op","chess_char_6_diy2_b",1,"none",2466,1,184,10,107105,2466,0,128,2],
["p1",3,"op","chess_char_6_diy1_b",2,"none",290,1,170,9,132099,4642,0,183,2],
["p1",4,"op","chess_char_6_diy2_b",0,"uniequip_002_demetr",2295.28,1,155,8,75695,3097,0,121,24],
["p1",5,"op","chess_char_6_diy1_b",1,"uniequip_002_demetr",1416,1,126,19,267864,3976,0,199,4],
["p1",6,"op","chess_char_6_diy2_b",2,"uniequip_002_demetr",2696,1,177,7,37347,2696,0,60,3],
["p1",7,"op","chess_char_5_diy1_a",0,null,1284,1,7,1,24310,0,0,45,7],
["p1",8,"op","chess_char_5_diy2_a",1,null,1284,1,10,0,33375,0,0,58,17],
["p1",1,"op","chess_char_6_diy1_b",0,"none",2466,1,179,1,13215,2466,0,36,7],
["p1",2,"op","chess_char_6_diy2_b",1,"none",2466,1,182,10,109343,2466,0,123,3],
["p1",3,"op","chess_char_6_diy1_b",2,"none",394,1,169,10,134345,4538,0,178,2],
["p1",4,"op","chess_char_6_diy2_b",0,"uniequip_002_demetr",2504,1,155,7,76906,2888,0,120,24],
["p1",5,"op","chess_char_6_diy1_b",1,"uniequip_002_demetr",1032,1,126,18,266716,4360,0,196,4],
["p1",6,"op","chess_char_6_diy2_b",2,"uniequip_002_demetr",2696,1,177,6,33576,2696,0,58,3],
["p1",7,"op","chess_char_5_diy1_a",0,null,1284,1,7,1,24332,0,0,45,7],
["p1",8,"op","chess_char_5_diy2_a",1,null,1284,1,10,0,32326,0,0,55,18],
["p1",9,"op","chess_char_5_diy1_a",2,null,1284,1,12,5,93033,0,0,65,4],
["p1",10,"op","chess_char_5_diy2_b",0,"none",1497,1,14,7,130869,0,0,68,9],
["p1",11,"op","chess_char_5_diy1_b",1,"none",1497,1,4,3,34716,0,0,46,17],
["p1",12,"op","chess_char_5_diy2_b",2,"none",1497,1,8,7,163326,0,0,70,5],
["p1",10,"op","chess_char_5_diy2_b",0,"none",1497,1,14,7,130833,0,0,68,9],
["p1",11,"op","chess_char_5_diy1_b",1,"none",1497,1,4,4,32623,0,0,45,16],
["p1",12,"op","chess_char_5_diy2_b",2,"none",1497,1,8,8,161391,0,0,68,5],
["-","~1","device","trap_1105_accrate",null,null,100,1,1,0,0,0,0,0,null],
["-","~2","device","trap_1105_accrate",null,null,100,1,2,0,0,0,0,0,null],
["-","~3","device","trap_1105_accrate",null,null,100,1,3,0,0,0,0,0,null],
@@ -2694,23 +2694,22 @@
["p1","~23","token","token_10008_cqbw_box",null,null,1000,0,141,1,7512,0,0,0,0],
["p1","~4","token","token_10065_demetr_dmtpos",null,null,1000,0,146,0,0,0,0,0,null],
["p1","~24","token","token_10008_cqbw_box",null,null,1000,0,147,0,764,0,0,0,0],
["p1","~25","token","token_10008_cqbw_box",null,null,1000,0,152,0,1546,0,0,0,0],
["p1","~25","token","token_10008_cqbw_box",null,null,1000,0,152,0,3054,0,0,0,0],
["p1","~26","token","token_10008_cqbw_box",null,null,1000,0,157,0,902,0,0,0,0],
["p1","~27","token","token_10008_cqbw_box",null,null,1000,0,162,0,1590,0,0,0,0],
["p1","~28","token","token_10008_cqbw_box",null,null,1000,1,165,0,0,0,0,0,0],
["p1","~29","token","token_10008_cqbw_box",null,null,1000,0,168,0,1422,0,0,0,0],
["p1","~27","token","token_10008_cqbw_box",null,null,1000,0,162,0,0,0,0,0,0],
["p1","~28","token","token_10008_cqbw_box",null,null,1000,0,165,0,1044,0,0,0,0],
["p1","~29","token","token_10008_cqbw_box",null,null,1000,0,170,0,1422,0,0,0,0],
["p1","~30","token","token_10008_cqbw_box",null,null,1000,1,173,0,0,0,0,0,0],
["p1","~5","token","token_10065_demetr_dmtpos",null,null,1000,1,178,0,0,0,0,0,null],
["p1","~31","token","token_10008_cqbw_box",null,null,1000,0,179,0,1590,0,0,0,0],
["p1","~32","token","token_10008_cqbw_box",null,null,1000,1,181,0,0,0,0,0,0],
["p1","~31","token","token_10008_cqbw_box",null,null,1000,0,178,0,1590,0,0,0,0],
["p1","~32","token","token_10008_cqbw_box",null,null,1000,1,180,0,0,0,0,0,0],
["p1","~33","token","token_10008_cqbw_box",null,null,1000,0,183,0,1590,0,0,0,0],
["p1","~34","token","token_10008_cqbw_box",null,null,1000,0,185,0,1785,0,0,0,0]
["p1","~34","token","token_10008_cqbw_box",null,null,1000,1,184,0,0,0,0,0,0]
],
"enemies": {"enemy_1116_liprr_2":[27,24,3,33,188265],"enemy_1119_vofsd":[48,37,11,3625,446823],"enemy_1121_lifbos_2":[30,20,10,15684,557022]},
"hooks": [1,185,6333,1206,1163,2136,2095,1241,87,146,101,131,0,43912,185,58,105,24,1,88,0,0,41],
"events": {"atk":1428,"deploy":77,"die":122,"dmg":2095,"engage":12,"fx":226,"leak":24,"skill":269,"spawn":159,"status":428},
"fx": {"aoe":57,"buff":6,"dodge":41,"liberate":11,"lock":26,"summon":34,"telegraph":31,"teleport":19,"undying":1},
"snaps": "b0838749 db2fae91 b18641ca 16c821b9 f6db7b40 1fa8cbba f1f0b4db 5b523ae2 f33e2f2f adbc97c4 238d413f 0defea06 c366a629 ff4c65f1 60e136ea b422498b a17f39bf c4a3088f 6bfdbba1 054df09a a720795a f5f6346d"
"enemies": {"enemy_1116_liprr_2":[27,24,3,17,188265],"enemy_1119_vofsd":[48,37,11,3817,446823],"enemy_1121_lifbos_2":[30,20,10,15580,551885]},
"hooks": [1,184,6219,1180,1137,2104,2065,1241,87,146,102,131,0,43429,184,56,105,24,1,88,0,0,39],
"events": {"atk":1400,"deploy":76,"die":122,"dmg":2065,"engage":12,"fx":231,"leak":24,"skill":270,"spawn":158,"status":431},
"fx": {"aoe":57,"buff":6,"dodge":39,"liberate":11,"lock":26,"phase":7,"summon":34,"telegraph":31,"teleport":19,"undying":1},
"snaps": "b0838749 db2fae91 b18641ca 16c821b9 f6db7b40 1fa8cbba f1f0b4db 5b523ae2 f33e2f2f adbc97c4 238d413f 0defea06 d17bb4cd 099c373d 077cd46a a9766c2d f8aa10a1 3a4c66f2 0f25f1ae 68aa750a 4b0acb0d"
},
"diy-066": {
"about": "5_diy1_b=cqbw/S1/002_cqbw 5_diy2_b=cqbw/S2/002_cqbw 5_diy1_b=cqbw/S3/002_cqbw 5_diy2_b=cqbw/S1/003_cqbw 5_diy1_b=cqbw/S2/003_cqbw 5_diy2_b=cqbw/S3/003_cqbw 6_diy1_a=cqbw/S1 6_diy2_a=cqbw/S2 6_diy1_a=cqbw/S3 6_diy2_b=cqbw/S1 6_diy1_b=cqbw/S2 6_diy2_b=cqbw/S3",
@@ -2724,24 +2723,24 @@
"time": 230,
"ticks": 6900,
"reason": "timeout",
"killed": 33,
"killed": 32,
"total": 105,
"unspawned": 0,
"bossHpLeft": null,
"rngDraws": 26,
"rngDraws": 21,
"errors": {"count":0,"kinds":[]},
"players": {"p1":{"killed":33,"total":105,"perfect":false,"leaks":72,"leaksUncounted":0,"coins":0,"dmg":1392503,"bossDmg":0,"heal":0,"deaths":6,"layerGains":{}}},
"players": {"p1":{"killed":32,"total":105,"perfect":false,"leaks":73,"leaksUncounted":0,"coins":0,"dmg":1377732,"bossDmg":0,"heal":0,"deaths":6,"layerGains":{}}},
"units": [
["p1",1,"op","chess_char_5_diy1_b",0,"uniequip_002_cqbw",1627,1,3,5,160987,0,0,78,11],
["p1",2,"op","chess_char_5_diy2_b",1,"uniequip_002_cqbw",1627,1,4,1,49546,0,0,59,20],
["p1",1,"op","chess_char_5_diy1_b",0,"uniequip_002_cqbw",1627,1,3,5,158055,0,0,78,11],
["p1",2,"op","chess_char_5_diy2_b",1,"uniequip_002_cqbw",1627,1,4,1,49824,0,0,59,20],
["p1",3,"op","chess_char_5_diy1_b",2,"uniequip_002_cqbw",1627,1,11,0,52837,0,0,48,4],
["p1",4,"op","chess_char_5_diy2_b",0,"uniequip_003_cqbw",1657,1,13,0,41465,0,0,42,8],
["p1",5,"op","chess_char_5_diy1_b",1,"uniequip_003_cqbw",1657,1,5,3,48317,0,0,60,20],
["p1",6,"op","chess_char_5_diy2_b",2,"uniequip_003_cqbw",1657,1,8,4,222259,0,0,72,6],
["p1",5,"op","chess_char_5_diy1_b",1,"uniequip_003_cqbw",1657,1,5,2,48221,0,0,60,20],
["p1",6,"op","chess_char_5_diy2_b",2,"uniequip_003_cqbw",1657,1,8,4,221695,0,0,72,6],
["p1",7,"op","chess_char_6_diy1_a",0,null,1284,1,12,1,109393,0,0,75,9],
["p1",8,"op","chess_char_6_diy2_a",1,null,1284,1,14,0,30571,0,0,54,17],
["p1",9,"op","chess_char_6_diy1_a",2,null,1284,1,9,1,136844,0,0,70,5],
["p1",10,"op","chess_char_6_diy2_b",0,"none",0,0,157,1,58088,2994,0,43,5],
["p1",10,"op","chess_char_6_diy2_b",0,"none",0,0,157,1,50113,2994,0,36,4],
["p1",11,"op","chess_char_6_diy1_b",1,"none",0,0,152,0,11145,2994,0,27,8],
["p1",12,"op","chess_char_6_diy2_b",2,"none",1497,1,188,2,34923,2994,0,29,2],
["-","~1","device","trap_1105_accrate",null,null,100,1,1,0,0,0,0,0,null],
@@ -2802,21 +2801,21 @@
["p1","~54","token","token_10008_cqbw_box",null,null,1000,0,172,0,7953,0,0,0,0],
["p1","~55","token","token_10008_cqbw_box",null,null,1000,0,173,0,10130,0,0,0,0],
["p1","~56","token","token_10008_cqbw_box",null,null,1000,0,174,0,3233,0,0,0,0],
["p1","~57","token","token_10008_cqbw_box",null,null,1000,0,178,0,2945,0,0,0,0],
["p1","~57","token","token_10008_cqbw_box",null,null,1000,0,178,0,3245,0,0,0,0],
["p1","~58","token","token_10008_cqbw_box",null,null,1000,0,179,0,2990,0,0,0,0],
["p1","~59","token","token_10008_cqbw_box",null,null,1000,0,181,0,864,0,0,0,0],
["p1","~60","token","token_10008_cqbw_box",null,null,1000,0,182,0,6830,0,0,0,0],
["p1","~61","token","token_10008_cqbw_box",null,null,1000,0,183,0,8166,0,0,0,0],
["p1","~60","token","token_10008_cqbw_box",null,null,1000,0,182,0,5108,0,0,0,0],
["p1","~61","token","token_10008_cqbw_box",null,null,1000,0,183,0,6106,0,0,0,0],
["p1","~62","token","token_10008_cqbw_box",null,null,1000,0,184,0,6090,0,0,0,0],
["p1","~63","token","token_10008_cqbw_box",null,null,1000,0,185,0,8837,0,0,0,0],
["p1","~64","token","token_10008_cqbw_box",null,null,1000,0,186,0,1797,0,0,0,0],
["p1","~65","token","token_10008_cqbw_box",null,null,1000,0,187,0,1823,0,0,0,0]
],
"enemies": {"enemy_1116_liprr_2":[27,26,1,0,334858],"enemy_1119_vofsd":[48,7,40,2651,603062],"enemy_1121_lifbos_2":[30,0,30,6331,492103]},
"hooks": [1,188,6900,770,688,3449,3431,3542,39,175,115,180,0,64747,562,10,105,71,1,39,0,0,18],
"events": {"atk":688,"deploy":81,"die":104,"dmg":3431,"engage":12,"fx":332,"leak":71,"skill":360,"spawn":184,"status":854},
"fx": {"aoe":108,"buff":14,"dodge":18,"liberate":19,"lock":43,"summon":65,"telegraph":65},
"snaps": "e329e6e0 0f7e0d1c 3e0f1718 4c3cf676 c7ea1a79 2f496e9b 268032c6 1686ece5 891c1773 712a1a14 f9896354 fba58506 1eead5c7 7fdba66a b37edb6b 1970c2ac a1c8bfda e6a59f73 d93c2505 f1389576 cacfa92a 6addf880 6eabfdb8"
"enemies": {"enemy_1116_liprr_2":[27,25,2,0,334495],"enemy_1119_vofsd":[48,7,40,2651,601962],"enemy_1121_lifbos_2":[30,0,30,6331,478795]},
"hooks": [1,188,6900,758,676,3440,3426,3542,38,175,114,179,0,64210,556,10,105,72,1,38,0,0,14],
"events": {"atk":676,"deploy":81,"die":103,"dmg":3426,"engage":12,"fx":331,"leak":72,"skill":358,"spawn":184,"status":850},
"fx": {"aoe":108,"buff":14,"dodge":14,"liberate":19,"lock":43,"phase":3,"summon":65,"telegraph":65},
"snaps": "e329e6e0 0f7e0d1c 3e0f1718 4c3cf676 c7ea1a79 2f496e9b 268032c6 1686ece5 891c1773 712a1a14 f9896354 fba58506 1eead5c7 7fdba66a b37edb6b 1970c2ac a1c8bfda cec1d512 69805149 05f93b94 d08ccc22 b7c16282 1a2d0524"
},
"diy-067": {
"about": "6_diy1_b=cqbw/S1/002_cqbw 6_diy2_b=cqbw/S2/002_cqbw 6_diy1_b=cqbw/S3/002_cqbw 6_diy2_b=cqbw/S1/003_cqbw 6_diy1_b=cqbw/S2/003_cqbw 6_diy2_b=cqbw/S3/003_cqbw 5_diy1_a=phenxi/S1 5_diy2_a=phenxi/S2 5_diy1_a=phenxi/S3 5_diy2_b=phenxi/S1 5_diy1_b=phenxi/S2 5_diy2_b=phenxi/S3",
@@ -3996,35 +3995,35 @@
"round": 12,
"seed": 3107422628,
"waveId": "act1autochess_h05",
"time": 210.37,
"ticks": 6311,
"reason": "cleared",
"killed": 0,
"time": 230,
"ticks": 6900,
"reason": "timeout",
"killed": 1,
"total": 90,
"unspawned": 0,
"bossHpLeft": null,
"rngDraws": 0,
"errors": {"count":0,"kinds":[]},
"players": {"p1":{"killed":0,"total":90,"perfect":false,"leaks":90,"leaksUncounted":0,"coins":0,"dmg":183010,"bossDmg":0,"heal":10291,"deaths":17,"layerGains":{}}},
"players": {"p1":{"killed":1,"total":90,"perfect":false,"leaks":89,"leaksUncounted":0,"coins":0,"dmg":194485,"bossDmg":0,"heal":7563,"deaths":19,"layerGains":{}}},
"units": [
["p1",1,"op","chess_char_5_diy1_a",0,null,0,0,93,0,15545,2972,294,40,3],
["p1",2,"op","chess_char_5_diy2_a",1,null,1339,1,7,0,0,0,0,0,4],
["p1",3,"op","chess_char_5_diy1_a",2,null,1339,1,9,0,17936,0,0,0,6],
["p1",4,"op","chess_char_5_diy2_b",0,"none",238.13,1,104,0,800,4766,0,31,1],
["p1",5,"op","chess_char_5_diy1_b",1,"none",1668,1,110,0,1996,4528,2860,71,3],
["p1",6,"op","chess_char_5_diy2_b",2,"none",0,0,91,0,17313,5183,1847,60,3],
["p1",7,"op","chess_char_5_diy1_b",0,"uniequip_002_sleach",0,0,70,0,14925,3636,0,46,2],
["p1",8,"op","chess_char_5_diy2_b",1,"uniequip_002_sleach",1350.92,1,108,0,25169,4683,2398,82,3],
["p1",9,"op","chess_char_5_diy1_b",2,"uniequip_002_sleach",0,0,88,0,53743,4124,488,69,3],
["p1",10,"op","chess_char_5_diy2_b",0,"uniequip_003_sleach",0,0,96,0,4213,3636,0,35,3],
["p1",11,"op","chess_char_5_diy1_b",1,"uniequip_003_sleach",1818,1,113,0,2135,4223,2405,79,3],
["p1",12,"op","chess_char_5_diy2_b",2,"uniequip_003_sleach",0,0,85,0,29235,3636,0,44,3]
["p1",1,"op","chess_char_5_diy1_a",0,null,1339,1,114,0,9850,2972,294,37,2],
["p1",2,"op","chess_char_5_diy2_a",1,null,1339,1,7,0,0,0,0,0,5],
["p1",3,"op","chess_char_5_diy1_a",2,null,1339,1,9,0,17548,0,0,0,6],
["p1",4,"op","chess_char_5_diy2_b",0,"none",238.13,1,105,0,800,4766,0,31,2],
["p1",5,"op","chess_char_5_diy1_b",1,"none",1668,1,101,0,1627,1668,0,56,4],
["p1",6,"op","chess_char_5_diy2_b",2,"none",0,0,87,0,16398,4406,1070,51,3],
["p1",7,"op","chess_char_5_diy1_b",0,"uniequip_002_sleach",0,0,70,0,15115,3636,0,51,2],
["p1",8,"op","chess_char_5_diy2_b",1,"uniequip_002_sleach",0,0,107,0,33214,5920,2284,75,2],
["p1",9,"op","chess_char_5_diy1_b",2,"uniequip_002_sleach",0,0,110,1,64784,7551,3915,114,4],
["p1",10,"op","chess_char_5_diy2_b",0,"uniequip_003_sleach",0,0,95,0,4231,3636,0,36,3],
["p1",11,"op","chess_char_5_diy1_b",1,"uniequip_003_sleach",0,0,99,0,4523,3636,0,44,2],
["p1",12,"op","chess_char_5_diy2_b",2,"uniequip_003_sleach",0,0,85,0,26396,3636,0,40,3]
],
"enemies": {"enemy_1116_liprr_2":[27,0,27,11196,136792],"enemy_1119_vofsd":[39,0,39,19761,29817],"enemy_1121_lifbos_2":[24,0,24,10429,16401]},
"hooks": [1,113,6311,630,630,734,734,3281,17,107,37,35,0,33266,12046,40,90,90,1,17,0,0,0],
"events": {"atk":630,"deploy":23,"die":17,"dmg":734,"engage":10,"fx":86,"leak":90,"skill":72,"spawn":102,"status":650},
"fx": {"aoe":15,"dp":36,"liberate":7,"zone":28},
"snaps": "9a75e65a d0a51d3d 37b53a2f 71340818 58c75009 2174e957 f216abaa 0cedce37 124bc8b3 cfd8fa1c bebfdf32 200747ac 8d973136 2ffe9099 448214d5 5a2edc2e 7b2fb345 453e18a7 0fc1936e e520c78d c8e2459a"
"enemies": {"enemy_1116_liprr_2":[27,1,26,15914,149729],"enemy_1119_vofsd":[39,0,38,15020,30521],"enemy_1121_lifbos_2":[24,0,24,10894,14235]},
"hooks": [1,114,6900,610,610,712,712,1680,20,108,38,36,0,33999,11632,42,90,88,1,20,0,0,0],
"events": {"atk":610,"deploy":24,"die":20,"dmg":712,"engage":10,"fx":95,"leak":88,"skill":74,"spawn":102,"status":692},
"fx": {"aoe":16,"dp":36,"liberate":5,"phase":9,"zone":29},
"snaps": "9a75e65a d0a51d3d 37b53a2f 0a085be8 2ab4df4b d33b871c b47093ca de7481ae c1c0243d 5c1fa8ed 0f0b10a5 b9e16e68 de7f017b 88430eae caaaf44a 0e0fcec8 ae7968ad f267712d 1143160b 5a739b4f b11f152f 889a0340 65ff2b9a"
},
"diy-095": {
"about": "6_diy1_a=sleach/S1 6_diy2_a=sleach/S2 6_diy1_a=sleach/S3 6_diy2_b=sleach/S1 6_diy1_b=sleach/S2 6_diy2_b=sleach/S3 6_diy1_b=sleach/S1/002_sleach 6_diy2_b=sleach/S2/002_sleach 6_diy1_b=sleach/S3/002_sleach 6_diy2_b=sleach/S1/003_sleach 6_diy1_b=sleach/S2/003_sleach 6_diy2_b=sleach/S3/003_sleach",
@@ -4127,40 +4126,40 @@
"round": 13,
"seed": 3733794685,
"waveId": "act1autochess_h06",
"time": 213.7,
"ticks": 6411,
"reason": "cleared",
"time": 230,
"ticks": 6900,
"reason": "timeout",
"killed": 5,
"total": 105,
"unspawned": 0,
"bossHpLeft": null,
"rngDraws": 203,
"errors": {"count":0,"kinds":[]},
"players": {"p1":{"killed":5,"total":105,"perfect":false,"leaks":100,"leaksUncounted":0,"coins":0,"dmg":618601,"bossDmg":0,"heal":0,"deaths":14,"layerGains":{}}},
"players": {"p1":{"killed":5,"total":105,"perfect":false,"leaks":100,"leaksUncounted":0,"coins":0,"dmg":676179,"bossDmg":0,"heal":0,"deaths":14,"layerGains":{}}},
"units": [
["p1",1,"op","chess_char_6_diy1_b",0,"none",1655,1,8,0,8070,0,0,166,11],
["p1",2,"op","chess_char_6_diy2_b",1,"none",1655,1,9,0,17815,0,0,177,3],
["p1",3,"op","chess_char_6_diy1_b",2,"none",1655,1,16,0,21206,0,0,158,3],
["p1",4,"op","chess_char_6_diy2_b",0,"uniequip_002_closur",1835,1,4,0,27520,0,0,193,11],
["p1",5,"op","chess_char_6_diy1_b",1,"uniequip_002_closur",1835,1,6,1,71387,0,0,193,3],
["p1",6,"op","chess_char_6_diy2_b",2,"uniequip_002_closur",1835,1,10,3,303284,0,0,274,3],
["p1",7,"op","chess_char_5_diy1_a",0,null,1124,1,17,1,102479,0,0,83,3],
["p1",1,"op","chess_char_6_diy1_b",0,"none",1655,1,8,0,8094,0,0,167,12],
["p1",2,"op","chess_char_6_diy2_b",1,"none",1655,1,9,0,17852,0,0,178,3],
["p1",3,"op","chess_char_6_diy1_b",2,"none",1655,1,16,0,21206,0,0,158,4],
["p1",4,"op","chess_char_6_diy2_b",0,"uniequip_002_closur",1835,1,4,0,36816,0,0,215,12],
["p1",5,"op","chess_char_6_diy1_b",1,"uniequip_002_closur",1835,1,6,0,83179,0,0,218,3],
["p1",6,"op","chess_char_6_diy2_b",2,"uniequip_002_closur",1835,1,10,4,344266,0,0,292,4],
["p1",7,"op","chess_char_5_diy1_a",0,null,1124,1,17,1,96438,0,0,84,3],
["p1",8,"op","chess_char_5_diy2_a",1,null,0,0,133,0,1960,3372,0,15,0],
["p1",9,"op","chess_char_5_diy1_a",2,null,0,0,130,0,1779,3372,0,11,0],
["p1",10,"op","chess_char_5_diy2_b",0,"none",0,0,143,0,14437,4080,0,12,1],
["p1",11,"op","chess_char_5_diy1_b",1,"none",1360,1,150,0,3920,2720,0,28,0],
["p1",12,"op","chess_char_5_diy2_b",2,"none",0,0,148,0,44744,4080,0,18,1],
["p1",9,"op","chess_char_5_diy1_a",2,null,1124,1,154,0,1779,3372,0,11,0],
["p1",10,"op","chess_char_5_diy2_b",0,"none",0,0,144,0,14437,4080,0,12,1],
["p1",11,"op","chess_char_5_diy1_b",1,"none",1360,1,149,0,3967,2720,0,28,0],
["p1",12,"op","chess_char_5_diy2_b",2,"none",0,0,150,0,46184,4080,0,23,1],
["-","~1","device","trap_1105_accrate",null,null,100,1,1,0,0,0,0,0,null],
["-","~2","device","trap_1105_accrate",null,null,100,1,2,0,0,0,0,0,null],
["p1","~1","token","token_10066_closur_ourbase",null,null,0,0,151,0,0,21378,0,0,0],
["p1","~2","token","token_10066_closur_ourbase",null,null,0,0,147,0,0,18324,0,0,0],
["p1","~3","token","token_10066_closur_ourbase",null,null,3054,1,152,0,0,18324,0,0,0]
["p1","~1","token","token_10066_closur_ourbase",null,null,0,0,152,0,0,21378,0,0,0],
["p1","~2","token","token_10066_closur_ourbase",null,null,1358.97,1,153,0,0,20019,0,0,0],
["p1","~3","token","token_10066_closur_ourbase",null,null,0,0,151,0,0,21378,0,0,0]
],
"enemies": {"enemy_1116_liprr_2":[27,5,22,8749,218950],"enemy_1119_vofsd":[48,0,48,33171,195033],"enemy_1121_lifbos_2":[30,0,30,33730,204617]},
"hooks": [1,149,6411,1499,1499,2344,2344,6518,38,138,39,58,0,32092,55,66,105,100,1,38,0,0,0],
"events": {"atk":2056,"deploy":42,"die":38,"dmg":2334,"engage":12,"fx":392,"leak":100,"skill":118,"spawn":122,"status":221},
"fx": {"disappear":19,"dp":40,"drone":203,"droneLock":34,"drones":5,"explode":22,"liberate":31,"shield":18,"summon":20},
"snaps": "5e23adc6 9a34be9b ddbcc9b6 84cf61fa 9d6983e2 225cb3c3 33a29f53 f98fc27e 6033275f 78951ff6 f7022aeb 8e6bc962 03bca500 fd44e418 a86e5704 16e166bd feecd8c7 218acaef 6bb7f281 4f6645a2 9374e154 a0a863f0"
"enemies": {"enemy_1116_liprr_2":[27,5,22,12390,235747],"enemy_1119_vofsd":[48,0,46,30712,224799],"enemy_1121_lifbos_2":[30,0,30,37297,215634]},
"hooks": [1,151,6900,1583,1583,2420,2420,6318,39,137,43,61,0,34701,55,70,105,98,1,39,0,0,0],
"events": {"atk":2139,"deploy":44,"die":39,"dmg":2408,"engage":12,"fx":425,"leak":98,"skill":126,"spawn":122,"status":221},
"fx": {"disappear":20,"dp":42,"drone":203,"droneLock":34,"drones":5,"explode":22,"liberate":31,"phase":27,"shield":20,"summon":21},
"snaps": "5e23adc6 9a34be9b 54cdf049 ab75cd31 21d5f975 9d87c804 e0bb73a4 251e829d 2d276f90 8c59c062 62bd3f06 e6397509 49ab0345 9de6cc83 aed71e7c 58606c87 41dc5ee7 f4ce2a35 d9f50934 1e28676d 70778663 a0597123 9b69313e"
},
"diy-098": {
"about": "5_diy1_b=gdglow/S1/002_gdglow 5_diy2_b=gdglow/S2/002_gdglow 5_diy1_b=gdglow/S3/002_gdglow 5_diy2_b=gdglow/S1/003_gdglow 5_diy1_b=gdglow/S2/003_gdglow 5_diy2_b=gdglow/S3/003_gdglow 6_diy1_a=gdglow/S1 6_diy2_a=gdglow/S2 6_diy1_a=gdglow/S3 6_diy2_b=gdglow/S1 6_diy1_b=gdglow/S2 6_diy2_b=gdglow/S3",
@@ -4422,20 +4421,20 @@
"time": 230,
"ticks": 6900,
"reason": "timeout",
"killed": 2,
"killed": 0,
"total": 90,
"unspawned": 0,
"bossHpLeft": null,
"rngDraws": 40,
"rngDraws": 37,
"errors": {"count":0,"kinds":[]},
"players": {"p1":{"killed":2,"total":90,"perfect":false,"leaks":88,"leaksUncounted":0,"coins":0,"dmg":162135,"bossDmg":0,"heal":0,"deaths":23,"layerGains":{}}},
"players": {"p1":{"killed":0,"total":90,"perfect":false,"leaks":90,"leaksUncounted":0,"coins":0,"dmg":136599,"bossDmg":0,"heal":0,"deaths":24,"layerGains":{}}},
"units": [
["p1",1,"op","chess_char_5_diy1_a",0,null,1322,1,120,1,6017,6610,0,71,6],
["p1",2,"op","chess_char_5_diy2_a",1,null,585.21,1,121,1,24450,6025,0,60,5],
["p1",3,"op","chess_char_5_diy1_a",2,null,1322,1,122,0,20231,5288,0,89,5],
["p1",4,"op","chess_char_5_diy2_b",0,"none",57.13,1,119,0,22264,6219,0,140,4],
["p1",5,"op","chess_char_5_diy1_b",1,"none",0,0,118,0,44873,4707,0,97,3],
["p1",6,"op","chess_char_5_diy2_b",2,"none",0,0,41,0,35923,3138,0,73,2],
["p1",1,"op","chess_char_5_diy1_a",0,null,0,0,120,0,2650,7932,0,69,6],
["p1",2,"op","chess_char_5_diy2_a",1,null,0.6,1,121,0,19053,7931,0,35,6],
["p1",3,"op","chess_char_5_diy1_a",2,null,1322,1,119,0,18819,3966,0,87,4],
["p1",4,"op","chess_char_5_diy2_b",0,"none",1569,1,122,0,18758,4707,0,101,4],
["p1",5,"op","chess_char_5_diy1_b",1,"none",0,0,108,0,35690,4707,0,90,3],
["p1",6,"op","chess_char_5_diy2_b",2,"none",0,0,41,0,33253,3138,0,67,2],
["p1",7,"op","chess_char_5_diy1_b",0,"uniequip_002_crosly",0,0,32,0,5020,3318,0,25,2],
["p1",8,"op","chess_char_5_diy2_b",1,"uniequip_002_crosly",1659,1,1,0,0,0,0,0,1],
["p1",9,"op","chess_char_5_diy1_b",2,"uniequip_002_crosly",1659,1,3,0,0,0,0,0,1],
@@ -4443,11 +4442,11 @@
["p1",11,"op","chess_char_5_diy1_b",1,"uniequip_003_crosly",1653,1,7,0,0,0,0,0,1],
["p1",12,"op","chess_char_5_diy2_b",2,"uniequip_003_crosly",1653,1,9,0,3356,0,0,2,1]
],
"enemies": {"enemy_1116_liprr_2":[27,2,25,10394,143020],"enemy_1119_vofsd":[39,0,37,14826,73253],"enemy_1121_lifbos_2":[24,0,24,10085,30582]},
"hooks": [1,122,6900,625,625,2809,2804,2819,25,111,32,31,0,0,40,27,90,86,1,25,0,0,5],
"events": {"atk":625,"deploy":32,"die":25,"dmg":2804,"engage":8,"fx":91,"leak":86,"skill":63,"spawn":102,"status":214},
"fx": {"aoe":10,"dodge":10,"liberate":22,"stealth":9,"strike":40},
"snaps": "128e2181 2918578e 40383091 c52c7314 5d3e75d3 21fd25ca ac1166dd ef3ba1b4 3ba202ee 4c367181 a9d20791 96e1fe7e 43146d6a e92f52eb 734bfb92 e4e3fddf 11c42322 b1a9d285 88bba952 46ada7bf e4707aee 0a08eedc dc69285c"
"enemies": {"enemy_1116_liprr_2":[27,0,27,7351,115533],"enemy_1119_vofsd":[39,0,38,14297,69755],"enemy_1121_lifbos_2":[24,0,24,14051,32711]},
"hooks": [1,122,6900,537,537,2637,2633,2731,24,113,32,31,0,0,39,25,90,89,1,24,0,0,4],
"events": {"atk":537,"deploy":32,"die":24,"dmg":2633,"engage":8,"fx":93,"leak":89,"skill":63,"spawn":102,"status":210},
"fx": {"aoe":9,"dodge":8,"liberate":21,"phase":8,"stealth":8,"strike":39},
"snaps": "128e2181 2918578e 40383091 c52c7314 5d3e75d3 21fd25ca ac1166dd ef3ba1b4 3ba202ee 4c367181 6dc0fc03 89758834 6768e16a 925ebfc0 56aa2704 e0281817 32ed3192 2e2c6034 603dd2df 89650f77 f04c240d 2bb4b65a f1abfe24"
},
"diy-105": {
"about": "6_diy1_a=crosly/S1 6_diy2_a=crosly/S2 6_diy1_a=crosly/S3 6_diy2_b=crosly/S1 6_diy1_b=crosly/S2 6_diy2_b=crosly/S3 6_diy1_b=crosly/S1/002_crosly 6_diy2_b=crosly/S2/002_crosly 6_diy1_b=crosly/S3/002_crosly 6_diy2_b=crosly/S1/003_crosly 6_diy1_b=crosly/S2/003_crosly 6_diy2_b=crosly/S3/003_crosly",
@@ -4458,35 +4457,35 @@
"round": 13,
"seed": 3007159473,
"waveId": "act1autochess_h06",
"time": 219.83,
"ticks": 6595,
"time": 216.5,
"ticks": 6495,
"reason": "cleared",
"killed": 2,
"killed": 3,
"total": 105,
"unspawned": 0,
"bossHpLeft": null,
"rngDraws": 45,
"errors": {"count":0,"kinds":[]},
"players": {"p1":{"killed":2,"total":105,"perfect":false,"leaks":103,"leaksUncounted":0,"coins":0,"dmg":139853,"bossDmg":0,"heal":0,"deaths":27,"layerGains":{}}},
"players": {"p1":{"killed":3,"total":105,"perfect":false,"leaks":102,"leaksUncounted":0,"coins":0,"dmg":156735,"bossDmg":0,"heal":0,"deaths":25,"layerGains":{}}},
"units": [
["p1",1,"op","chess_char_6_diy1_a",0,null,0,0,134,0,5106,6610,0,93,5],
["p1",1,"op","chess_char_6_diy1_a",0,null,0,0,134,0,13912,6610,0,77,5],
["p1",2,"op","chess_char_6_diy2_a",1,null,1322,1,7,0,0,0,0,0,1],
["p1",3,"op","chess_char_6_diy1_a",2,null,1322,1,9,0,1386,0,0,1,1],
["p1",4,"op","chess_char_6_diy2_b",0,"none",1569,1,136,0,10886,6276,0,105,5],
["p1",5,"op","chess_char_6_diy1_b",1,"none",0,0,130,0,21895,6276,0,69,4],
["p1",6,"op","chess_char_6_diy2_b",2,"none",1569,1,135,1,39549,4707,0,92,4],
["p1",7,"op","chess_char_6_diy1_b",0,"uniequip_002_crosly",0,0,119,0,5750,5097,0,77,3],
["p1",4,"op","chess_char_6_diy2_b",0,"none",0,0,119,1,22300,6276,0,114,4],
["p1",5,"op","chess_char_6_diy1_b",1,"none",1569,1,130,0,23834,4707,0,70,4],
["p1",6,"op","chess_char_6_diy2_b",2,"none",1569,1,135,1,37325,4707,0,72,4],
["p1",7,"op","chess_char_6_diy1_b",0,"uniequip_002_crosly",1699,1,124,0,2795,3398,0,53,3],
["p1",8,"op","chess_char_6_diy2_b",1,"uniequip_002_crosly",0,0,63,0,26282,3398,0,34,2],
["p1",9,"op","chess_char_6_diy1_b",2,"uniequip_002_crosly",0,0,44,1,20149,3398,0,51,2],
["p1",10,"op","chess_char_6_diy2_b",0,"uniequip_003_crosly",0,0,71,0,4862,3408,0,38,2],
["p1",10,"op","chess_char_6_diy2_b",0,"uniequip_003_crosly",0,0,71,0,4764,3408,0,35,2],
["p1",11,"op","chess_char_6_diy1_b",1,"uniequip_003_crosly",0,0,3,0,781,1704,0,7,1],
["p1",12,"op","chess_char_6_diy2_b",2,"uniequip_003_crosly",0,0,5,0,3208,1704,0,11,1]
],
"enemies": {"enemy_1116_liprr_2":[27,2,25,7459,77227],"enemy_1119_vofsd":[48,0,48,27256,46672],"enemy_1121_lifbos_2":[30,0,30,7863,15955]},
"hooks": [1,136,6595,707,707,750,744,5531,29,132,31,29,0,0,32,29,105,103,1,29,0,0,6],
"events": {"atk":707,"deploy":31,"die":29,"dmg":744,"engage":11,"fx":95,"leak":103,"skill":60,"spawn":117,"status":227},
"fx": {"aoe":8,"dodge":17,"liberate":30,"stealth":8,"strike":32},
"snaps": "f90f7e34 cd1e8118 e0c584b3 87fac72d 0d01dc30 05d4cc5b a4e6ded0 751a1305 65d9a3ab 626ad747 d63d426e 770a82d5 71763629 728661e2 ffa336b4 9a5d1981 8a58b535 8b9eb65b 741936b9 6b60bcb2 deea77c8 b551a8d7"
"enemies": {"enemy_1116_liprr_2":[27,3,24,9238,103724],"enemy_1119_vofsd":[48,0,48,25477,41700],"enemy_1121_lifbos_2":[30,0,30,4595,11311]},
"hooks": [1,135,6495,642,642,687,680,4572,28,130,30,29,0,0,32,28,105,102,1,28,0,0,7],
"events": {"atk":642,"deploy":30,"die":28,"dmg":680,"engage":11,"fx":108,"leak":102,"skill":59,"spawn":117,"status":225},
"fx": {"aoe":8,"dodge":16,"liberate":29,"phase":15,"stealth":8,"strike":32},
"snaps": "f90f7e34 cd1e8118 e0c584b3 87fac72d 0d01dc30 05d4cc5b 42b3d463 8a0d04de 207145fe c945755a f5d05911 4b71d0b2 4ee1ba65 3944fdae c18355e1 526a095c 1caa274a 179b5d05 ba8c6245 ef950474 843b370c 6854a22f"
},
"diy-106": {
"about": "5_diy1_a=lmlee/S1 5_diy2_a=lmlee/S2 5_diy1_a=lmlee/S3 5_diy2_b=lmlee/S1 5_diy1_b=lmlee/S2 5_diy2_b=lmlee/S3 5_diy1_b=lmlee/S1/002_lmlee 5_diy2_b=lmlee/S2/002_lmlee 5_diy1_b=lmlee/S3/002_lmlee 5_diy2_b=lmlee/S1/003_lmlee 5_diy1_b=lmlee/S2/003_lmlee 5_diy2_b=lmlee/S3/003_lmlee",
@@ -5452,26 +5451,26 @@
"time": 230,
"ticks": 6900,
"reason": "timeout",
"killed": 24,
"killed": 29,
"total": 105,
"unspawned": 0,
"bossHpLeft": null,
"rngDraws": 0,
"errors": {"count":0,"kinds":[]},
"players": {"p1":{"killed":24,"total":105,"perfect":false,"leaks":81,"leaksUncounted":0,"coins":0,"dmg":1650261,"bossDmg":0,"heal":0,"deaths":14,"layerGains":{}}},
"players": {"p1":{"killed":29,"total":105,"perfect":false,"leaks":76,"leaksUncounted":0,"coins":0,"dmg":1853747,"bossDmg":0,"heal":0,"deaths":11,"layerGains":{}}},
"units": [
["p1",1,"op","chess_char_5_diy1_a",0,null,0,0,136,0,1894,4084,0,71,2],
["p1",1,"op","chess_char_5_diy1_a",0,null,2042,1,136,0,5212,2042,0,73,3],
["p1",2,"op","chess_char_5_diy2_a",1,null,2042,1,6,0,0,0,0,0,0],
["p1",3,"op","chess_char_5_diy1_a",2,null,2042,1,9,0,0,0,0,0,0],
["p1",4,"op","chess_char_5_diy2_b",0,"none",0,0,122,0,2284,7479,0,34,1],
["p1",5,"op","chess_char_5_diy1_b",1,"none",2493,1,116,0,4849,2493,0,97,2],
["p1",6,"op","chess_char_5_diy2_b",2,"none",0,0,108,0,5911,4986,0,102,2],
["p1",7,"op","chess_char_6_diy1_b",0,"none",1111,1,1,2,196758,0,0,94,23],
["p1",8,"op","chess_char_6_diy2_b",1,"none",617.59,1,93,0,99799,1604,0,73,2],
["p1",9,"op","chess_char_6_diy1_b",2,"none",274.62,1,86,7,395548,1947,0,91,3],
["p1",10,"op","chess_char_6_diy2_b",0,"uniequip_002_phatm2",1311,1,128,7,312774,1311,0,81,19],
["p1",11,"op","chess_char_6_diy1_b",1,"uniequip_002_phatm2",817.59,1,82,4,267720,1804,0,110,2],
["p1",12,"op","chess_char_6_diy2_b",2,"uniequip_002_phatm2",0,0,80,4,362723,2622,0,62,2],
["p1",4,"op","chess_char_5_diy2_b",0,"none",0,0,122,0,1784,7479,0,32,1],
["p1",5,"op","chess_char_5_diy1_b",1,"none",2493,1,116,0,3553,2493,0,60,1],
["p1",6,"op","chess_char_5_diy2_b",2,"none",880.85,1,105,0,6414,4105,0,118,3],
["p1",7,"op","chess_char_6_diy1_b",0,"none",1111,1,1,2,189868,0,0,100,25],
["p1",8,"op","chess_char_6_diy2_b",1,"none",617.59,1,93,2,86133,1604,0,81,2],
["p1",9,"op","chess_char_6_diy1_b",2,"none",274.62,1,86,7,372331,1947,0,89,3],
["p1",10,"op","chess_char_6_diy2_b",0,"uniequip_002_phatm2",1311,1,128,4,282336,1311,0,80,19],
["p1",11,"op","chess_char_6_diy1_b",1,"uniequip_002_phatm2",817.59,1,82,9,319127,1804,0,110,2],
["p1",12,"op","chess_char_6_diy2_b",2,"uniequip_002_phatm2",474.62,1,80,5,586990,2147,0,96,3],
["p1","~1","token","token_10055_phatm2_mndclv",null,null,2,0,28,0,0,3,0,0,null],
["p1","~2","token","token_10055_phatm2_mndclv",null,null,3,0,29,0,0,0,0,0,null],
["p1","~3","token","token_10055_phatm2_mndclv",null,null,3,0,30,0,0,0,0,0,null],
@@ -5483,24 +5482,20 @@
["p1","~9","token","token_10055_phatm2_mndclv",null,null,3,0,0,0,0,0,0,0,null],
["p1","~10","token","token_10055_phatm2_mndclv",null,null,3,0,101,0,0,0,0,0,null],
["p1","~11","token","token_10055_phatm2_mndclv",null,null,3,0,0,0,0,0,0,0,null],
["p1","~12","token","token_10055_phatm2_mndclv",null,null,1,0,103,0,0,8,0,0,null],
["p1","~12","token","token_10055_phatm2_mndclv",null,null,3,0,103,0,0,3,0,0,null],
["p1","~13","token","token_10055_phatm2_mndclv",null,null,2,0,111,0,0,1,0,0,null],
["p1","~14","token","token_10055_phatm2_mndclv",null,null,3,0,0,0,0,0,0,0,null],
["p1","~15","token","token_10055_phatm2_mndclv",null,null,3,0,0,0,0,0,0,0,null],
["p1","~16","token","token_10055_phatm2_mndclv",null,null,2,0,113,0,0,1,0,0,null],
["p1","~17","token","token_10055_phatm2_mndclv",null,null,3,0,0,0,0,0,0,0,null],
["p1","~18","token","token_10055_phatm2_mndclv",null,null,3,0,0,0,0,0,0,0,null],
["p1","~19","token","token_10055_phatm2_mndclv",null,null,3,0,0,0,0,0,0,0,null],
["p1","~20","token","token_10055_phatm2_mndclv",null,null,3,0,0,0,0,0,0,0,null],
["p1","~21","token","token_10055_phatm2_mndclv",null,null,3,0,0,0,0,0,0,0,null],
["p1","~22","token","token_10055_phatm2_mndclv",null,null,3,0,0,0,0,0,0,0,null],
["p1","~23","token","token_10055_phatm2_mndclv",null,null,3,0,0,0,0,0,0,0,null]
["p1","~16","token","token_10055_phatm2_mndclv",null,null,1,0,113,0,0,3,0,0,null],
["p1","~17","token","token_10055_phatm2_mndclv",null,null,3,0,137,0,0,0,0,0,null],
["p1","~18","token","token_10055_phatm2_mndclv",null,null,3,1,138,0,0,0,0,0,null],
["p1","~19","token","token_10055_phatm2_mndclv",null,null,3,0,139,0,0,0,0,0,null]
],
"enemies": {"enemy_1116_liprr_2":[27,10,17,6558,300820],"enemy_1119_vofsd":[48,11,37,8677,699049],"enemy_1121_lifbos_2":[30,3,25,13110,650392]},
"hooks": [1,136,6900,877,877,1169,3394,0,38,126,58,55,0,20263,271,77,105,79,1,38,0,230,0],
"events": {"atk":898,"deploy":31,"die":47,"dmg":3394,"engage":10,"fx":464,"leak":79,"skill":113,"spawn":126,"status":684},
"fx": {"burst":230,"liberate":2,"palsy":223,"summon":9},
"snaps": "2a0507a2 4f58543c 93d3e4d9 9648970b ca3b9e42 bd8380d0 2eb8b298 587df1aa dfee693f c1b4681b caeea197 f3f4068d 8e5f3ff8 c66ffeae 29d2da90 17bc5bce cf2d4279 42b38cf0 f9833847 94e94777 9f8f767d d859ace3 984a03d2"
"enemies": {"enemy_1116_liprr_2":[27,11,16,5051,311245],"enemy_1119_vofsd":[48,15,32,7665,797037],"enemy_1121_lifbos_2":[30,3,23,12228,745466]},
"hooks": [1,139,6900,890,890,1210,3636,0,40,122,62,57,0,20883,301,75,105,71,1,40,0,258,0],
"events": {"atk":910,"deploy":34,"die":51,"dmg":3636,"engage":10,"fx":523,"leak":71,"skill":119,"spawn":129,"status":745},
"fx": {"burst":258,"liberate":2,"palsy":248,"phase":3,"summon":12},
"snaps": "2a0507a2 4f58543c 93d3e4d9 9648970b ca3b9e42 bd8380d0 5c661dc1 02a3bec0 22a89519 27a78677 9899fc56 eab6d820 348b2e9c 0497802c 534aa27b f386a0eb e69e5054 7e066d71 f59932ac c9ececcd 64cda8cd 10cc7f3a 50dcc5e3"
},
"diy-128": {
"about": "5_diy1_b=ironmn/S1/002_ironmn 5_diy2_b=ironmn/S2/002_ironmn 5_diy1_b=ironmn/S3/002_ironmn 5_diy2_b=ironmn/S1/003_ironmn 5_diy1_b=ironmn/S2/003_ironmn 5_diy2_b=ironmn/S3/003_ironmn 6_diy1_a=ironmn/S1 6_diy2_a=ironmn/S2 6_diy1_a=ironmn/S3 6_diy2_b=ironmn/S1 6_diy1_b=ironmn/S2 6_diy2_b=ironmn/S3",
+12 -12
View File
@@ -469,11 +469,11 @@
},
{
"round": 6,
"ai_0": [1,15,9,0,0,3,8,"12a1dcbb",16,"arcaneShip 0/4, kazimierzShip 0/2, kjeragShip 0/4, lateranoShip 0/3, preciShip 1/4, sargonShip 0/2, steadShip 2/4, swiftShip 1/8",16,21,5,38]
"ai_0": [1,15,9,0,1,3,8,"12a1dcbb",16,"arcaneShip 0/4, kazimierzShip 0/2, kjeragShip 0/4, lateranoShip 0/3, preciShip 1/4, sargonShip 0/2, steadShip 2/4, swiftShip 1/8",16,21,5,38]
},
{
"round": 7,
"ai_0": [1,13,10,0,0,4,8,"932a36c9",18,"arcaneShip 0/4, kazimierzShip 1/2, kjeragShip 0/4, lateranoShip 0/3, preciShip 1/4, sargonShip 0/2, soloShip 1/0, steadShip 2/4, swiftShip 1/8",26,28,2,50]
"ai_0": [1,13,11,0,0,4,8,"932a36c9",18,"arcaneShip 0/4, kazimierzShip 1/2, kjeragShip 0/4, lateranoShip 0/3, preciShip 1/4, sargonShip 0/2, soloShip 1/0, steadShip 2/4, swiftShip 1/8",26,28,2,50]
},
{
"round": 8,
@@ -499,7 +499,7 @@
"title": {"id":"comment_4","name":"精英云集","picId":"comment_icon_4","text":"晋升精锐次数最多"},
"trophies": 0,
"reward": 191,
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":1255869,"gold":88,"itemsEquipped":8,"kills":143,"leaks":42,"lpLost":37,"merges":2,"perfectRounds":3,"refreshes":6},
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":1256554,"gold":88,"itemsEquipped":8,"kills":143,"leaks":42,"lpLost":37,"merges":2,"perfectRounds":3,"refreshes":6},
"lineup": [],
"bonds": ["arcaneShip 0/18","kazimierzShip 0/4","kjeragShip 0/16","lateranoShip 0/3","preciShip 0/13","sargonShip 0/2","steadShip 0/8","swiftShip 0/10"]
}
@@ -610,7 +610,7 @@
"title": {"id":"comment_1","name":"卫戍之星","picId":"comment_icon_1","text":"对敌方领袖造成伤害最高(仅胜利时)"},
"trophies": 4,
"reward": 400,
"stats": {"activatedLayers":199,"bossDamage":926528,"dmgDealt":3823060,"gold":137,"itemsEquipped":18,"kills":325,"leaks":6,"lpLost":6,"merges":5,"perfectRounds":12,"refreshes":13},
"stats": {"activatedLayers":199,"bossDamage":926528,"dmgDealt":3823020,"gold":137,"itemsEquipped":18,"kills":325,"leaks":6,"lpLost":6,"merges":5,"perfectRounds":12,"refreshes":13},
"lineup": ["4_20_a@12,8[3_06_e_a]","1_17_b@11,7[3_08_e_a]","4_02_b@11,8[3_02_e_a+4_03_e_b]","4_01_b@10,7[4_04_e_a+1_02_e_a]","6_17_a@10,8[4_06_e_a+4_08_e_a]","6_19_a@9,7[1_05_e_a+1_01_e_b]","4_14_a@9,8","5_07_a@9,9"],
"bonds": ["arcaneShip 2/34","kazimierzShip 1/38","kjeragShip 0/8","lateranoShip 0/8","preciShip 2/55","raidShip 1/0","sargonShip 0/10","suntShip 1/0","swiftShip 1/72"]
}
@@ -798,20 +798,20 @@
{
"round": 10,
"ai_0": [1,6,18,0,0,5,8,"7365b613",209,"deputShip 2/36, indomShip 1/8, kazimierzShip 0/2, kjeragShip 1/43, miraShip 1/4, skillfulShip 1/57, soloShip 1/20, steadShip 1/33, suntShip 1/8, swiftShip 0/20",15,18,3,99],
"ai_1": [1,13,12,0,0,5,8,"8f07e1d3",124,"deputShip 2/40, indomShip 1/5, kazimierzShip 0/7, skillfulShip 1/26, soloShip 1/20, suntShip 0/16, swiftShip 0/21, victoriaShip 1/33",3,18,15,85],
"ai_2": [0,0,12,0,0,5,0,"811c9dc5",0,"deputShip 0/10, miraShip 0/5, siracusaShip 0/84, soloShip 0/22, suntShip 0/6, swiftShip 0/23, yanShip 0/1",9,18,9,86]
"ai_1": [1,13,12,0,0,5,8,"8f07e1d3",124,"deputShip 2/40, indomShip 1/5, kazimierzShip 0/7, skillfulShip 1/26, soloShip 1/20, suntShip 0/16, swiftShip 0/21, victoriaShip 1/33",4,18,14,85],
"ai_2": [0,0,12,0,0,5,0,"811c9dc5",0,"deputShip 0/10, miraShip 0/6, siracusaShip 0/86, soloShip 0/22, suntShip 0/6, swiftShip 0/23, yanShip 0/1",6,18,12,86]
},
{
"round": 11,
"ai_0": [1,3,12,0,1,5,8,"3d2ea997",260,"deputShip 2/40, indomShip 0/8, kazimierzShip 0/2, kjeragShip 1/59, miraShip 1/8, siracusaShip 0/6, skillfulShip 1/69, soloShip 1/24, steadShip 1/44, suntShip 1/12, swiftShip 0/26, visiShip 1/4",22,25,3,111],
"ai_1": [1,3,12,0,0,5,8,"ec0a9e7a",133,"deputShip 1/46, indomShip 1/11, kazimierzShip 0/7, maniShip 1/2, skillfulShip 1/28, soloShip 0/20, suntShip 0/16, swiftShip 0/21, victoriaShip 2/46",8,25,17,98],
"ai_2": [0,0,0,0,0,5,0,"811c9dc5",0,"deputShip 0/10, miraShip 0/5, siracusaShip 0/84, soloShip 0/22, suntShip 0/6, swiftShip 0/23, yanShip 0/1",null,null,null,86]
"ai_2": [0,0,0,0,0,5,0,"811c9dc5",0,"deputShip 0/10, miraShip 0/6, siracusaShip 0/86, soloShip 0/22, suntShip 0/6, swiftShip 0/23, yanShip 0/1",null,null,null,86]
},
{
"round": 12,
"ai_0": [0,0,13,0,0,6,0,"811c9dc5",0,"deputShip 0/44, indomShip 0/8, kazimierzShip 0/2, kjeragShip 0/65, miraShip 0/12, siracusaShip 0/6, skillfulShip 0/81, soloShip 0/28, steadShip 0/55, suntShip 0/16, swiftShip 0/26, visiShip 0/8",14,57,43,125],
"ai_1": [0,0,12,0,0,6,0,"811c9dc5",0,"deputShip 0/48, indomShip 0/17, kazimierzShip 0/7, maniShip 0/4, skillfulShip 0/30, soloShip 0/20, suntShip 0/16, swiftShip 0/21, victoriaShip 0/67",11,57,46,109],
"ai_2": [0,0,0,0,0,5,0,"811c9dc5",0,"deputShip 0/10, miraShip 0/5, siracusaShip 0/84, soloShip 0/22, suntShip 0/6, swiftShip 0/23, yanShip 0/1",null,null,null,86]
"ai_2": [0,0,0,0,0,5,0,"811c9dc5",0,"deputShip 0/10, miraShip 0/6, siracusaShip 0/86, soloShip 0/22, suntShip 0/6, swiftShip 0/23, yanShip 0/1",null,null,null,86]
}
],
"players": {
@@ -839,7 +839,7 @@
"title": {"id":"comment_6","name":"挥金如土","picId":"comment_icon_6","text":"消耗资金最多"},
"trophies": 2,
"reward": 255,
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":2189200,"gold":109,"itemsEquipped":9,"kills":241,"leaks":109,"lpLost":52,"merges":3,"perfectRounds":5,"refreshes":18},
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":2183297,"gold":109,"itemsEquipped":9,"kills":242,"leaks":108,"lpLost":52,"merges":3,"perfectRounds":5,"refreshes":18},
"lineup": [],
"bonds": ["deputShip 0/48","indomShip 0/17","kazimierzShip 0/7","maniShip 0/4","skillfulShip 0/30","soloShip 0/20","suntShip 0/16","swiftShip 0/21","victoriaShip 0/67"]
},
@@ -853,9 +853,9 @@
"title": {"id":"comment_5","name":"万事俱备","picId":"comment_icon_5","text":"装备配发数量最多"},
"trophies": 2,
"reward": 191,
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":1594236,"gold":86,"itemsEquipped":5,"kills":205,"leaks":39,"lpLost":28,"merges":2,"perfectRounds":4,"refreshes":14},
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":1540634,"gold":86,"itemsEquipped":5,"kills":202,"leaks":42,"lpLost":29,"merges":2,"perfectRounds":4,"refreshes":14},
"lineup": [],
"bonds": ["deputShip 0/10","miraShip 0/5","siracusaShip 0/84","soloShip 0/22","suntShip 0/6","swiftShip 0/23","yanShip 0/1"]
"bonds": ["deputShip 0/10","miraShip 0/6","siracusaShip 0/86","soloShip 0/22","suntShip 0/6","swiftShip 0/23","yanShip 0/1"]
}
}
},
@@ -1333,7 +1333,7 @@
},
{
"round": 7,
"ai_0": [1,400,10,0,0,4,8,"2606af8a",607,"arcaneShip 0/302, deputShip 0/300, egirShip 0/300, emptyShip 0/300, indomShip 0/300, investShip 0/300, kazimierzShip 0/308, kjeragShip 0/300, lateranoShip 0/300, maniShip 0/300, miraShip 0/300, preciShip 0/302, raidShip 0/300, sargonShip 0/300, siracusaShip 0/300, skillfulShip 0/300, soloShip 1/307, steadShip 1/300, suntShip 0/300, swiftShip 0/308, victoriaShip 0/300, visiShip 0/300, yanShip 0/300",25,25,0,51]
"ai_0": [1,400,10,0,0,4,8,"00e5b748",607,"arcaneShip 0/302, deputShip 0/300, egirShip 0/300, emptyShip 0/300, indomShip 0/300, investShip 0/300, kazimierzShip 0/308, kjeragShip 0/300, lateranoShip 0/300, maniShip 0/300, miraShip 0/300, preciShip 0/302, raidShip 0/300, sargonShip 0/300, siracusaShip 0/300, skillfulShip 0/300, soloShip 1/307, steadShip 1/300, suntShip 0/300, swiftShip 0/308, victoriaShip 0/300, visiShip 0/300, yanShip 0/300",25,25,0,51]
},
{
"round": 8,
+73 -73
View File
@@ -62,8 +62,8 @@
"enemy_9010_acpupp": [1,0,0,0,654]
},
"hooks": [1,50,2700,396,396,681,682,329,32,32,26,23,16,15196,105,33,31,0,1,33,0,0,0],
"events": {"atk":440,"bounty":4,"deploy":16,"die":32,"dmg":682,"engage":11,"fx":67,"heal":321,"skill":52,"spawn":47,"status":123},
"fx": {"aoe":2,"bombard":8,"bombardShell":9,"counter":6,"crit":19,"dp":2,"ember":1,"explode":4,"heal":12,"summon":1,"taunt":1,"telegraph":1,"zone":1},
"events": {"atk":440,"bounty":4,"deploy":16,"die":32,"dmg":682,"engage":11,"fx":69,"heal":321,"skill":52,"spawn":47,"status":123},
"fx": {"aoe":2,"bombard":8,"bombardShell":9,"counter":6,"crit":19,"dp":2,"ember":1,"explode":4,"heal":12,"phase":2,"summon":1,"taunt":1,"telegraph":1,"zone":1},
"snaps": "15544384 8d3c7635 48c925ab 4c3fe49b cd3cfaa1 c157b224 2c9ae13b 3a55280f 20b3165f"
},
"roster-002": {
@@ -182,8 +182,8 @@
"enemy_9016_acstmr": [1,1,0,0,8]
},
"hooks": [1,105,3300,569,569,689,804,222,86,90,24,23,0,16353,226,29,85,0,1,94,1,0,0],
"events": {"atk":670,"bounty":6,"deploy":17,"die":90,"dmg":774,"engage":9,"fx":108,"heal":192,"layer":1,"skill":47,"spawn":101,"status":223},
"fx": {"aoe":1,"blink":1,"displace":8,"ember":1,"explode":10,"garrison":1,"heal":5,"pulse":42,"reveal":1,"revive":1,"sleep":8,"summon":25,"undying":1,"zone":3},
"events": {"atk":670,"bounty":6,"deploy":17,"die":90,"dmg":774,"engage":9,"fx":109,"heal":192,"layer":1,"skill":47,"spawn":101,"status":223},
"fx": {"aoe":1,"blink":1,"displace":8,"ember":1,"explode":10,"garrison":1,"heal":5,"phase":1,"pulse":42,"reveal":1,"revive":1,"sleep":8,"summon":25,"undying":1,"zone":3},
"snaps": "c29e3835 28b841b8 3ea22a73 67a6b520 35d0349a 97ef8a6d 86c3dbf5 9d20d292 f19b1a3f 70f1741b 20c76bb6"
},
"roster-004": {
@@ -204,19 +204,19 @@
"bossHpLeft": null,
"rngDraws": 2,
"errors": {"count":0,"kinds":[]},
"players": {"p1":{"killed":9,"total":36,"perfect":false,"leaks":27,"leaksUncounted":0,"coins":2,"dmg":112805,"bossDmg":0,"heal":20365,"deaths":13,"layerGains":{}}},
"players": {"p1":{"killed":9,"total":36,"perfect":false,"leaks":27,"leaksUncounted":0,"coins":2,"dmg":106469,"bossDmg":0,"heal":20437,"deaths":13,"layerGains":{}}},
"units": [
["p1",1,"op","chess_char_2_08_a",1,null,0,0,8,1,5701,10301,148,4,0],
["p1",2,"op","chess_char_2_17_a",1,null,0,0,6,0,3626,7897,1734,2,2],
["p1",3,"op","chess_char_2_18_a",0,null,0,0,9,0,26482,8005,147,14,1],
["p1",4,"op","chess_char_2_07_a",1,null,0,0,10,0,7125,6231,0,9,1],
["p1",1,"op","chess_char_2_08_a",1,null,0,0,8,1,4451,10064,148,4,0],
["p1",2,"op","chess_char_2_17_a",1,null,0,0,6,0,5229,7897,1734,2,2],
["p1",3,"op","chess_char_2_18_a",0,null,0,0,9,1,20733,7498,147,12,1],
["p1",4,"op","chess_char_2_07_a",1,null,0,0,10,0,6215,6468,0,8,1],
["p1",5,"op","chess_char_2_09_a",1,null,1513.21,1,56,0,6902,5702,1638,19,1],
["p1",6,"op","chess_char_2_11_a",1,null,0,0,12,1,18832,7470,113,25,1],
["p1",7,"op","chess_char_2_13_a",1,null,3122.65,1,57,2,10661,3169,22,20,1],
["p1",8,"op","chess_char_2_16_a",1,null,3098.43,1,54,0,5438,4790,139,15,0],
["p1",9,"op","chess_char_2_12_a",1,null,0,0,52,4,12322,4404,0,42,2],
["p1",10,"op","chess_char_2_06_a",0,null,0,0,4,0,0,3062,12070,22,7],
["p1",11,"op","chess_char_2_10_a",1,null,0,0,5,1,9674,2406,0,51,1],
["p1",9,"op","chess_char_2_12_a",1,null,0,0,52,4,12322,4664,0,42,2],
["p1",10,"op","chess_char_2_06_a",0,null,0,0,4,0,0,3382,12142,22,7],
["p1",11,"op","chess_char_2_10_a",1,null,0,0,5,0,9644,2406,0,51,1],
["p1",12,"op","chess_char_2_14_a",1,null,2131.36,1,55,0,0,3763,4306,9,0],
["-","~1","device","trap_1105_accrate",null,null,100,1,1,0,0,0,0,0,null],
["-","~2","device","trap_1105_accrate",null,null,100,1,2,0,0,0,0,0,null],
@@ -224,26 +224,26 @@
["p1","~1","token","token_10022_kazema_shadow",null,null,0,0,26,0,6042,1864,48,6,null]
],
"enemies": {
"enemy_1001_bigbo": [1,0,1,6870,4832],
"enemy_1006_shield": [1,0,1,3483,9381],
"enemy_10118_ymgprc": [1,0,1,6271,9669],
"enemy_1041_lazerd_2": [1,0,1,6338,4317],
"enemy_1118_lidbox_2": [1,1,0,3643,16416],
"enemy_1158_divman": [18,8,10,6618,62957],
"enemy_1160_hvyslr": [3,0,3,3906,12041],
"enemy_1161_tidmag": [3,0,2,6444,10438],
"enemy_1169_duphlx_2": [1,0,1,1292,9579],
"enemy_1001_bigbo": [1,0,1,6870,6759],
"enemy_1006_shield": [1,0,1,3045,4801],
"enemy_10118_ymgprc": [1,0,1,6271,7771],
"enemy_1041_lazerd_2": [1,0,1,6459,4317],
"enemy_1118_lidbox_2": [1,1,0,4642,16416],
"enemy_1158_divman": [18,8,10,6705,62407],
"enemy_1160_hvyslr": [3,0,3,3830,11425],
"enemy_1161_tidmag": [3,0,2,6714,9938],
"enemy_1169_duphlx_2": [1,0,1,820,8954],
"enemy_1200_msfjin_2": [1,0,1,0,21],
"enemy_1249_lysdb_2": [1,0,1,0,1467],
"enemy_1249_lysdb_2": [1,0,1,0,838],
"enemy_1299_ymkilr": [1,0,1,0,560],
"enemy_1389_winbab_2": [1,0,1,1089,1330],
"enemy_1389_winbab_2": [1,0,1,992,1330],
"enemy_1504_cqbw": [1,0,1,652,630],
"enemy_2009_csaudc": [1,0,1,0,490]
},
"hooks": [1,57,3300,442,442,1431,1451,1360,23,49,17,17,0,10816,33,32,36,26,1,28,0,2,0],
"events": {"atk":516,"bounty":1,"deploy":18,"die":23,"dmg":1382,"engage":11,"fx":20,"heal":87,"leak":26,"skill":34,"spawn":52,"status":171},
"fx": {"aoe":4,"burst":2,"camouflage":2,"dodge":3,"dollEnd":1,"liberate":1,"overload":1,"shield":2,"shieldBreak":1,"substitute":1,"summon":1,"takeoff":1},
"snaps": "95c7197d e941625e 33d925c4 10072f4f 8653b032 4756b7f2 793e7802 2917ae3a ca138fc6 daff5cf1 784c4992"
"hooks": [1,57,3300,435,435,1379,1400,1360,23,49,17,17,0,10761,29,32,36,26,1,28,0,2,0],
"events": {"atk":511,"bounty":1,"deploy":18,"die":23,"dmg":1333,"engage":11,"fx":21,"heal":88,"leak":26,"skill":34,"spawn":52,"status":166},
"fx": {"aoe":4,"burst":2,"camouflage":2,"dodge":3,"dollEnd":1,"liberate":1,"overload":1,"phase":1,"shield":2,"shieldBreak":1,"substitute":1,"summon":1,"takeoff":1},
"snaps": "95c7197d e941625e 33d925c4 1cb46719 50ed098d ac7e8334 ebe1dbfe ec21f87b 8d1c3a8b ca59f49a 4fa1da8c"
},
"roster-005": {
"about": "pass 0 band 3: chess_char_2_07_b chess_char_2_08_b chess_char_2_09_b chess_char_2_11_b chess_char_2_12_b chess_char_2_19_a chess_char_2_01_b chess_char_2_02_b chess_char_2_04_b chess_char_2_05_b chess_char_2_06_b chess_char_2_10_b token_10000_silent_healrb",
@@ -436,8 +436,8 @@
"enemy_2021_syfish": [1,0,1,0,1177]
},
"hooks": [1,191,4200,568,568,814,818,380,120,179,30,29,0,17736,14,39,167,58,1,128,0,0,0],
"events": {"atk":700,"bounty":2,"deploy":22,"die":121,"dmg":807,"engage":14,"fx":137,"leak":58,"skill":59,"spawn":183,"status":53},
"fx": {"aoe":2,"camouflage":1,"displace":25,"dp":2,"explode":19,"pull":25,"revive":2,"sp":1,"strike":3,"summon":45,"volley":7,"wolfShadow":2,"wolfShadowLost":3},
"events": {"atk":700,"bounty":2,"deploy":22,"die":121,"dmg":807,"engage":14,"fx":138,"leak":58,"skill":59,"spawn":183,"status":53},
"fx": {"aoe":2,"camouflage":1,"displace":25,"dp":2,"explode":19,"phase":1,"pull":25,"revive":2,"sp":1,"strike":3,"summon":45,"volley":7,"wolfShadow":2,"wolfShadowLost":3},
"snaps": "1e865453 bf5ab273 b3945eb6 be85e6ff 52a3ef1a 3ce79014 31baf8e7 dd4cf502 b5b135c5 243437eb cb9f7bb5 83316176 fd0bb4b8 e4d97127"
},
"roster-008": {
@@ -1402,9 +1402,9 @@
"enemy_2085_skzjxd_2": [1,0,1,0,6175]
},
"hooks": [1,45,3167,599,599,710,718,809,32,34,50,48,32,10597,106,28,29,1,1,32,0,0,0],
"events": {"atk":669,"bounty":4,"deploy":13,"die":33,"dmg":706,"engage":12,"fx":44,"heal":15,"leak":1,"skill":98,"spawn":44,"status":248},
"fx": {"crit":30,"dp":4,"explode":1,"liberate":6,"shield":2,"telegraph":1},
"snaps": "08475251 060e1404 0207c267 f5a6179e 68f495e6 09ed84e5 8460cd2e 568cfe46 ac0133c8 b5de44d8 a3326504"
"events": {"atk":669,"bounty":4,"deploy":13,"die":33,"dmg":706,"engage":12,"fx":46,"heal":15,"leak":1,"skill":98,"spawn":44,"status":248},
"fx": {"crit":30,"dp":4,"explode":1,"liberate":6,"phase":2,"shield":2,"telegraph":1},
"snaps": "08475251 060e1404 0207c267 f5a6179e 68f495e6 09ed84e5 c0890ff9 741e1189 2a8a50b5 61078709 d9ed48e1"
},
"roster-022": {
"about": "pass 1 band 2: chess_char_1_10_b chess_char_1_12_b chess_char_1_20_b chess_char_1_18_b chess_char_1_19_b chess_char_1_13_b chess_char_1_14_b chess_char_1_17_b chess_char_2_01_a chess_char_2_02_a chess_char_2_04_a chess_char_2_05_a",
@@ -1418,25 +1418,25 @@
"time": 110,
"ticks": 3300,
"reason": "timeout",
"killed": 18,
"killed": 16,
"total": 28,
"unspawned": 0,
"bossHpLeft": null,
"rngDraws": 116,
"rngDraws": 123,
"errors": {"count":0,"kinds":[]},
"players": {"p1":{"killed":18,"total":28,"perfect":false,"leaks":10,"leaksUncounted":0,"coins":4,"dmg":237071,"bossDmg":0,"heal":21732,"deaths":4,"layerGains":{}}},
"players": {"p1":{"killed":16,"total":28,"perfect":false,"leaks":12,"leaksUncounted":0,"coins":4,"dmg":218727,"bossDmg":0,"heal":23247,"deaths":5,"layerGains":{}}},
"units": [
["p1",1,"op","chess_char_1_10_b",1,"none",2343,1,7,1,9452,10116,2908,33,2],
["p1",1,"op","chess_char_1_10_b",1,"none",2343,1,7,1,9452,10789,2483,33,2],
["p1",2,"op","chess_char_1_12_b",0,"none",0,0,8,3,26490,7197,1113,22,1],
["p1",3,"op","chess_char_1_20_b",0,"none",0,0,6,1,4578,8524,0,12,6],
["p1",4,"op","chess_char_1_18_b",0,"none",3194,1,9,0,857,3526,1826,1,3],
["p1",3,"op","chess_char_1_20_b",0,"none",0,0,6,0,2212,10364,0,15,6],
["p1",4,"op","chess_char_1_18_b",0,"none",2154.82,1,9,0,2827,5890,3101,4,3],
["p1",5,"op","chess_char_1_19_b",0,"none",0,0,10,2,20799,7996,0,43,1],
["p1",6,"op","chess_char_1_13_b",0,"none",1095,1,3,0,20166,0,2871,56,2],
["p1",7,"op","chess_char_1_14_b",0,"none",1430,1,4,6,97417,500,0,36,2],
["p1",6,"op","chess_char_1_13_b",0,"none",1095,1,3,0,20166,0,3150,56,2],
["p1",7,"op","chess_char_1_14_b",0,"none",1430,1,4,6,92214,500,0,34,2],
["p1",8,"op","chess_char_1_17_b",0,"none",1356,1,12,1,19542,1000,0,6,3],
["p1",9,"op","chess_char_2_01_a",0,null,677.6,1,35,0,5908,678,0,9,0],
["p1",10,"op","chess_char_2_02_a",0,null,1400,1,5,0,0,1000,9974,41,2],
["p1",11,"op","chess_char_2_04_a",0,null,977,1,11,4,31863,4704,0,57,15],
["p1",10,"op","chess_char_2_02_a",0,null,1400,1,5,0,0,1000,10359,42,2],
["p1",11,"op","chess_char_2_04_a",0,null,0,0,11,3,19118,2684,0,37,10],
["p1",12,"op","chess_char_2_05_a",0,null,1411.2,1,13,0,0,4240,3040,6,1],
["-","~1","device","trap_1105_accrate",null,null,100,1,1,0,0,0,0,0,null],
["-","~2","device","trap_1105_accrate",null,null,100,1,2,0,0,0,0,0,null]
@@ -1444,19 +1444,19 @@
"enemies": {
"enemy_1007_slime": [1,1,0,0,950],
"enemy_1025_reveng": [1,1,0,556,8640],
"enemy_1116_liprr": [12,10,0,1631,107786],
"enemy_1116_liprr_2": [6,4,2,3736,69832],
"enemy_1121_lifbos": [3,0,2,2477,20157],
"enemy_1116_liprr": [12,9,1,1761,102034],
"enemy_1116_liprr_2": [6,3,2,4315,60076],
"enemy_1121_lifbos": [3,0,2,2476,16173],
"enemy_1160_hvyslr": [1,1,0,2131,17280],
"enemy_1200_msfjin": [1,1,0,0,30],
"enemy_1272_nhtank": [1,0,1,21982,16184],
"enemy_1272_nhtank": [1,0,1,20811,15808],
"enemy_1404_msnip": [1,0,1,3966,6593],
"enemy_2002_bearmi": [1,0,1,4301,4561]
"enemy_2002_bearmi": [1,0,1,7439,6083]
},
"hooks": [1,43,3300,427,427,1002,996,737,22,29,38,37,0,15328,144,32,28,7,1,22,0,0,0],
"events": {"atk":455,"bounty":2,"deploy":13,"die":22,"dmg":996,"engage":10,"fx":32,"heal":515,"leak":7,"skill":75,"spawn":42,"status":276},
"fx": {"buff":2,"crit":3,"liberate":10,"shield":12,"zone":5},
"snaps": "f47a9f8c 739344e4 42c68dd5 faaf4ae5 644d0d43 0ae18c03 48ee2a13 8adefc93 eb27bc9f ba13681b e37842d2"
"hooks": [1,43,3300,417,417,965,959,853,21,29,33,32,0,14367,118,30,28,8,1,21,0,0,0],
"events": {"atk":440,"bounty":2,"deploy":13,"die":21,"dmg":959,"engage":10,"fx":39,"heal":506,"leak":8,"skill":65,"spawn":42,"status":252},
"fx": {"buff":2,"crit":3,"liberate":10,"phase":7,"shield":12,"zone":5},
"snaps": "f47a9f8c 739344e4 42c68dd5 faaf4ae5 644d0d43 0ae18c03 48ee2a13 361c35bd 57cf0060 98fe7afd 7022eb85"
},
"roster-023": {
"about": "pass 1 band 2: chess_char_2_08_a chess_char_2_17_a chess_char_2_18_a chess_char_2_07_a chess_char_2_09_a chess_char_2_11_a chess_char_2_13_a chess_char_2_16_a chess_char_2_12_a chess_char_2_06_a chess_char_2_10_a chess_char_2_14_a",
@@ -1563,8 +1563,8 @@
"enemy_1535_wlfmster": [1,0,1,8984,18836]
},
"hooks": [1,203,4200,756,756,1044,1111,2414,169,190,68,65,0,13911,1032,49,191,21,1,177,0,0,0],
"events": {"atk":965,"bounty":3,"deploy":12,"die":169,"dmg":1064,"engage":8,"fx":77,"heal":151,"leak":21,"skill":133,"spawn":203,"status":529},
"fx": {"beam":3,"buff":5,"summon":57,"undying":1,"zone":11},
"events": {"atk":965,"bounty":3,"deploy":12,"die":169,"dmg":1064,"engage":8,"fx":78,"heal":151,"leak":21,"skill":133,"spawn":203,"status":529},
"fx": {"beam":3,"buff":5,"phase":1,"summon":57,"undying":1,"zone":11},
"snaps": "3528dfb7 48905850 aff1c414 d4b44f71 7e706a8f c4a07a93 5e5052bc b45c5d36 ebbfc908 a20e4f9f 666701cc e6e998e9 e042a19b 9fc624e8"
},
"roster-025": {
@@ -1639,22 +1639,22 @@
"total": 73,
"unspawned": 0,
"bossHpLeft": null,
"rngDraws": 167,
"rngDraws": 164,
"errors": {"count":0,"kinds":[]},
"players": {"p1":{"killed":15,"total":73,"perfect":false,"leaks":58,"leaksUncounted":0,"coins":6,"dmg":173830,"bossDmg":0,"heal":1327,"deaths":18,"layerGains":{}}},
"players": {"p1":{"killed":15,"total":73,"perfect":false,"leaks":58,"leaksUncounted":0,"coins":6,"dmg":172523,"bossDmg":0,"heal":1327,"deaths":18,"layerGains":{}}},
"units": [
["p1",1,"op","chess_char_3_12_a",0,null,0,0,96,3,6989,4668,1327,19,3],
["p1",2,"op","chess_char_3_16_a",0,null,0,0,6,0,3318,2173,0,11,1],
["p1",3,"op","chess_char_3_18_a",0,null,0,0,95,2,6903,2962,0,5,4],
["p1",4,"op","chess_char_3_08_a",0,null,0,0,4,2,28106,1594,0,8,1],
["p1",5,"op","chess_char_3_09_a",0,null,1267,1,99,1,14376,1267,0,22,3],
["p1",2,"op","chess_char_3_16_a",0,null,0,0,6,0,3190,2173,0,11,1],
["p1",3,"op","chess_char_3_18_a",0,null,0,0,93,1,4796,2962,0,4,3],
["p1",4,"op","chess_char_3_08_a",0,null,0,0,4,1,30700,1594,0,8,1],
["p1",5,"op","chess_char_3_09_a",0,null,1267,1,99,2,14769,1267,0,22,3],
["p1",6,"op","chess_char_3_10_a",0,null,0,0,86,1,26456,3300,0,17,4],
["p1",7,"op","chess_char_3_11_a",0,null,0,0,7,1,11464,1316,0,7,1],
["p1",8,"op","chess_char_3_13_a",0,null,0,0,10,0,5136,4736,0,27,1],
["p1",9,"op","chess_char_3_14_a",0,null,0,0,75,0,6873,2502,0,8,0],
["p1",10,"op","chess_char_3_17_a",0,null,284.9,1,94,3,38866,4207,0,52,10],
["p1",8,"op","chess_char_3_13_a",0,null,0,0,10,0,4799,4736,0,27,1],
["p1",9,"op","chess_char_3_14_a",0,null,0,0,75,0,5911,2502,0,7,0],
["p1",10,"op","chess_char_3_17_a",0,null,938.6,1,95,3,38866,3553,0,52,10],
["p1",11,"op","chess_char_3_19_a",0,null,0,0,79,1,16258,2878,0,29,0],
["p1",12,"op","chess_char_3_20_a",0,null,0,0,97,0,4210,2684,0,20,1],
["p1",12,"op","chess_char_3_20_a",0,null,0,0,97,0,3447,2684,0,18,1],
["p1",13,"token","token_10028_vigil_wolf",null,null,51.51,0,15,1,3733,828,0,6,null],
["-","~1","device","trap_1105_accrate",null,null,100,1,1,0,0,0,0,0,null],
["-","~2","device","trap_1105_accrate",null,null,100,1,2,0,0,0,0,0,null],
@@ -1662,23 +1662,23 @@
["p1","~1","token","token_10028_vigil_wolf",null,null,0,0,80,0,1145,1579,0,4,null]
],
"enemies": {
"enemy_10042_prtrop": [12,0,12,7015,23122],
"enemy_10042_prtrop": [12,0,12,6413,21834],
"enemy_10042_prtrop_2": [12,0,10,4427,15485],
"enemy_10043_sailor": [39,8,31,17297,162191],
"enemy_10043_sailor": [39,8,31,16646,159545],
"enemy_1005_yokai_2": [1,1,0,68,2678],
"enemy_10156_mncrer": [1,1,0,140,6912],
"enemy_1116_liprr_2": [1,1,0,1736,12960],
"enemy_1116_liprr_2": [1,1,0,2415,15356],
"enemy_1195_sfyin_2": [1,1,0,294,5357],
"enemy_1196_msfyin_2": [2,2,0,0,6],
"enemy_1251_lysyta_2": [1,1,0,495,7925],
"enemy_1355_mrfly_2": [1,0,1,0,5433],
"enemy_1513_dekght_2": [1,0,1,3475,1400],
"enemy_1513_dekght_2": [1,0,1,3473,1400],
"enemy_9010_acpupp": [1,0,1,0,1540]
},
"hooks": [1,98,4200,362,362,1435,1494,8,34,91,29,29,0,8574,25,35,73,56,1,38,0,0,0],
"events": {"atk":420,"bounty":3,"deploy":22,"die":35,"dmg":1492,"engage":14,"fx":25,"heal":8,"leak":56,"skill":58,"spawn":90,"status":52},
"fx": {"dp":4,"explode":4,"liberate":1,"palsy":1,"revive":4,"shield":2,"sp":2,"strike":1,"summon":2,"telegraph":3,"wolfShadowLost":1},
"snaps": "b048220b 78ebd5ff 0274759f 4737dad6 5932437f 85e05e52 5a39defd 7e9cbcda 7ec8fe69 002d7498 b320dd19 dce2b580 df4e7bdd 78bea99e"
"hooks": [1,98,4200,354,354,1421,1482,9,34,91,28,28,0,8507,30,36,73,56,1,38,0,0,0],
"events": {"atk":413,"bounty":3,"deploy":22,"die":35,"dmg":1480,"engage":14,"fx":22,"heal":9,"leak":56,"skill":56,"spawn":90,"status":57},
"fx": {"dp":3,"explode":3,"liberate":1,"phase":1,"revive":4,"shield":2,"sp":2,"strike":1,"summon":2,"telegraph":2,"wolfShadowLost":1},
"snaps": "b048220b 78ebd5ff 0274759f 0c8cd24d 1366fed1 15a201b9 b5ba8640 4392779a 3960fa36 ca328f1c 3007dd06 fb8e1623 2149ac25 f795894d"
},
"roster-027": {
"about": "pass 1 band 4: chess_char_3_06_b chess_char_3_12_b chess_char_3_02_b chess_char_3_03_b chess_char_3_04_b chess_char_3_05_b chess_char_3_21_a chess_char_3_01_b chess_char_3_08_b chess_char_3_09_b chess_char_3_10_b chess_char_3_11_b",
@@ -2080,8 +2080,8 @@
"enemy_9011_acrefr": [1,0,1,0,1527]
},
"hooks": [1,198,6664,961,961,3404,3432,2289,59,192,68,67,0,23204,206,88,167,132,1,65,7,0,3],
"events": {"atk":1050,"bounty":1,"deploy":29,"die":60,"dmg":3390,"engage":12,"fx":118,"heal":451,"layer":7,"leak":132,"skill":135,"spawn":182,"status":264},
"fx": {"aoe":3,"dodge":3,"dollEnd":3,"garrison":7,"healAoe":4,"hpShare":1,"palsy":1,"reborn":3,"revive":6,"shield":39,"sp":10,"substitute":3,"summon":1,"zone":34},
"events": {"atk":1050,"bounty":1,"deploy":29,"die":60,"dmg":3390,"engage":12,"fx":119,"heal":451,"layer":7,"leak":132,"skill":135,"spawn":182,"status":264},
"fx": {"aoe":3,"dodge":3,"dollEnd":3,"garrison":7,"healAoe":4,"hpShare":1,"palsy":1,"phase":1,"reborn":3,"revive":6,"shield":39,"sp":10,"substitute":3,"summon":1,"zone":34},
"snaps": "8b9c3026 e0f96062 a49bbfa8 29d89b05 0acdd66d 607a3e6e e487bee7 925b98be 8d6d2209 5c9e2d74 878a99ae 98ba61a3 429c3a4d 28fa2b80 5f6aa75e 47b6d9dc 12bc9401 62c44e64 d6f464bb de487d8c 7aaa2057 21893dc4 3ac24c00"
},
"roster-034": {
+27 -27
View File
@@ -24,7 +24,7 @@
"total": 50,
"unspawned": 0,
"bossHpLeft": null,
"rngDraws": 595,
"rngDraws": 404,
"errors": {"count":0,"kinds":[]},
"players": {
"p1": {
@@ -34,44 +34,44 @@
"leaks": 28,
"leaksUncounted": 0,
"coins": 4,
"dmg": 280742,
"dmg": 266162,
"bossDmg": 0,
"heal": 26765,
"deaths": 19,
"heal": 16178,
"deaths": 23,
"layerGains": {"raidShip":13,"visiShip":2}
}
},
"units": [
["p1",1,"op","chess_char_3_12_a",2,null,0,0,73,3,40405,3648,0,20,2],
["p1",2,"op","chess_char_4_09_a",0,null,458.8,1,83,5,55322,5509,0,34,2],
["p1",3,"op","chess_char_3_05_a",2,null,1865.8,1,77,3,29828,11858,0,46,2],
["p1",4,"op","chess_char_3_18_a",2,null,2638,1,7,2,32526,8770,0,75,2],
["p1",5,"op","chess_char_4_04_a",1,null,1264.1,1,91,2,17806,8706,0,100,9],
["p1",6,"op","chess_char_4_07_a",1,null,0,0,74,1,16008,10455,0,37,1],
["p1",7,"op","chess_char_4_16_a",1,null,807.8,1,92,1,9136,11490,0,98,14],
["p1",8,"op","chess_char_3_01_a",2,null,1271,1,5,0,15937,0,0,131,2],
["p1",9,"op","chess_char_3_04_a",2,null,1218,1,8,0,0,0,26765,59,3],
["p1",10,"op","chess_char_3_21_a",2,null,161.7,1,6,1,42388,1110,0,121,2],
["p1",11,"op","chess_char_4_02_a",1,null,1272,1,93,3,11537,1724,0,61,1],
["p1",12,"op","chess_char_4_13_a",1,null,812,1,84,1,9849,812,0,27,1]
["p1",1,"op","chess_char_3_12_a",2,null,0,0,73,4,63063,4029,0,26,3],
["p1",2,"op","chess_char_4_09_a",0,null,333.6,1,82,4,41987,5634,0,33,2],
["p1",3,"op","chess_char_3_05_a",2,null,1442.3,1,75,2,30691,11964,0,46,2],
["p1",4,"op","chess_char_3_18_a",2,null,0,0,7,0,12109,3090,0,27,1],
["p1",5,"op","chess_char_4_04_a",1,null,951,1,90,2,20875,5420,0,75,9],
["p1",6,"op","chess_char_4_07_a",1,null,0,0,76,1,16997,12466,0,39,1],
["p1",7,"op","chess_char_4_16_a",1,null,0,0,88,1,7848,10473,0,110,10],
["p1",8,"op","chess_char_3_01_a",2,null,1271,1,5,2,25558,0,0,144,2],
["p1",9,"op","chess_char_3_04_a",2,null,1218,1,83,0,0,1218,16178,35,2],
["p1",10,"op","chess_char_3_21_a",2,null,1272,1,89,3,26523,1272,0,58,1],
["p1",11,"op","chess_char_4_02_a",1,null,0,0,9,2,11150,1653,0,50,1],
["p1",12,"op","chess_char_4_13_a",1,null,812,1,84,1,9361,812,0,25,1]
],
"enemies": {
"enemy_10001_trslim": [1,1,0,8,4860],
"enemy_1000_gopro_2": [1,1,0,0,1836],
"enemy_10018_sgrobh": [1,1,0,2811,8100],
"enemy_1001_bigbo": [1,0,1,1301,3217],
"enemy_10027_vtsk": [1,0,1,16122,2471],
"enemy_10018_sgrobh": [1,1,0,3793,8100],
"enemy_1001_bigbo": [1,0,1,2157,2613],
"enemy_10027_vtsk": [1,0,1,12395,936],
"enemy_10031_cnvsld": [1,0,1,0,0],
"enemy_10034_cnvsax": [1,0,1,0,0],
"enemy_10034_cnvsax": [1,0,1,808,2545],
"enemy_10042_prtrop": [1,0,1,0,0],
"enemy_1116_liprr_2": [21,12,9,5347,131366],
"enemy_1119_vofsd": [12,6,6,19166,93491],
"enemy_1121_lifbos_2": [9,1,7,9882,35401]
"enemy_1116_liprr_2": [21,14,7,7342,129693],
"enemy_1119_vofsd": [12,4,7,12831,76140],
"enemy_1121_lifbos_2": [9,1,7,8976,39440]
},
"hooks": [1,93,5100,939,939,1515,1509,3842,41,82,41,39,0,22264,26,41,50,27,1,41,5,0,6],
"events": {"atk":1088,"bounty":2,"deploy":43,"die":55,"dmg":1509,"engage":11,"fx":61,"heal":59,"layer":5,"leak":27,"skill":80,"spawn":62,"status":123},
"fx": {"blink":14,"dodge":7,"dp":5,"garrison":5,"liberate":13,"slash":16,"telegraph":1},
"snaps": "8b8be66d 3d41101a 548df15a 1009f8b0 08d13c52 9fe4b099 64799759 70e168de 0b87fdee 880a5dbc 4750bf5e 71d1cbac a6d3a940 eda8aa0d 5dec048f 8b7b727d 0b96370a"
"hooks": [1,90,5100,782,782,1274,1278,2889,45,81,35,32,0,17872,24,38,50,26,1,46,5,0,3],
"events": {"atk":875,"bounty":2,"deploy":40,"die":55,"dmg":1278,"engage":11,"fx":87,"heal":35,"layer":5,"leak":26,"skill":67,"spawn":62,"status":127},
"fx": {"beam":8,"blink":10,"dodge":3,"dp":7,"garrison":5,"liberate":16,"phase":13,"slash":24,"telegraph":1},
"snaps": "8b8be66d b3674b6a 84ebce5a 655e2381 01458f80 5429a40f 79ef58a7 e0c853b0 b82a9af1 80ef3ca7 cfdb8a3a 47523368 7134b000 32056871 69a04f4b c6c5ecc7 e01e6b80"
},
"standin-02": {
"about": "normal band 5 as stand-ins: chess_char_4_17_a→char_610_acfend chess_char_4_18_a→char_602_cdfend chess_char_5_05_a→char_602_cdfend chess_char_4_19_a→char_608_acpion chess_char_5_01_a→char_600_cpione chess_char_4_22_a→char_609_acguad chess_char_4_23_a→char_609_acguad chess_char_5_06_a→char_609_acguad chess_char_4_20_a→char_603_csnipe chess_char_4_24_a→char_604_ccast chess_char_5_02_a→char_604_ccast chess_char_5_03_a→char_612_accast",
@@ -0,0 +1,162 @@
// test/render/feedback5-prisoners.browser.test.js — community report of 2026-10-06 「囚徒类敌人出门就是已解放的模型」 in
// headless Chrome, on the 2D and the 3D board: the real sim runs in the page (the client runner's loadBrowserSim) and
// feeds the render demo's field view. Three operators block three 孤岛风云 prisoners — 普通囚犯, 强壮囚犯 and 拳师囚犯, one
// of each clip-naming family — and each model follows its official prefab's modes: the grey confined set out of the gate, the
// blinking orange set from the warning (before the last confined attack), the red set once freed (sim fx 'phase' /
// 'liberate' with their `form` → render/units.js FORMS). 普通囚犯 used to come out on its red (freed) set and none ever
// changed. Screenshots (cropped to the prisoners) → test/e2e/out/prisoners-<board>-<confined|warning|freed>.png.
//
// Opt-in (starts Chrome): RENDER_E2E=1 node --test test/render/feedback5-prisoners.browser.test.js
// Needs the downloaded assets; the 3D board also the local-client board art and WebGL2 (else that half is skipped).
// Chrome path: $CHROME_PATH or the macOS default.
import { test, describe, before, after } from 'node:test';
import assert from 'node:assert/strict';
import { existsSync, mkdirSync } from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { buildBattleSpec } from '../../server/sim/spec.js';
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..');
const OUT = path.join(ROOT, 'test/e2e/out');
const CHROME = process.env.CHROME_PATH || '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome';
const enabled = process.env.RENDER_E2E === '1' && existsSync(CHROME) && existsSync(path.join(ROOT, 'public/assets'));
const skip = enabled ? false : 'set RENDER_E2E=1 (needs Chrome and downloaded assets)';
/** Each prisoner's clip suffix per mode (confined / warning / freed), as test/render/feedback5-prisoners.test.js. */
const SETS = {
enemy_1116_liprr: ['3', '2', ''],
enemy_1119_vofsd: ['', '2', '3'],
enemy_1118_lidbox_2: ['_grey', '_orange', '_red'],
};
const KEYS = Object.keys(SETS);
// three block-1 operators along act2 m01's road (9,10) → (9,8) → (12,7) → (12,5) → (9,5) → (9,2): 山 on (9,8), 宴 on
// (12,6), 斯卡蒂 on (10,5), each facing the coming enemies; the prisoners walk in 1 s apart, harmless and tanky, and each
// is blocked by its own operator — they stand apart and keep attacking until freed
const SPEC = buildBattleSpec({
battleId: 'e2e.prisoners', fieldId: 'n:P1', kind: 'normal', seed: 5, modeId: 'mode_multi_hard', round: 12, stageId: 'act2autochess_m01', timeLimit: 400,
players: [{ playerId: 'P1', seat: 0, side: 'L', colOffset: 0, units: [
{ uid: 1, kind: 'chess', chessId: 'chess_char_5_17_a', row: 9, col: 8, dir: 'RIGHT' },
{ uid: 2, kind: 'chess', chessId: 'chess_char_1_18_a', row: 12, col: 6, dir: 'RIGHT' },
{ uid: 3, kind: 'chess', chessId: 'chess_char_3_05_a', row: 10, col: 5, dir: 'DOWN' },
], bonds: {}, playerEffects: [] }],
spawns: KEYS.map((enemyKey, i) => ({ time: i, enemyKey, routeIndex: 0, count: 1, mods: { hpMul: 200, atkMul: 0.01 } })),
routes: [{ motion: 'WALK', start: [9, 10], end: [9, 2], checkpoints: [] }], flags: {},
});
const setOf = (key, clip) => {
const m = /^(?:Idle|Move|Attack|Die|Default)(.*)$/.exec(clip || '');
return m ? SETS[key].indexOf(m[1]) : -1;
};
describe('the 孤岛风云 prisoners draw confined → warning → freed (headless Chrome, real sim)', { skip }, () => {
let srv, browser;
before(async () => {
const puppeteer = (await import('puppeteer-core')).default;
const { startServer } = await import('../../server/index.js');
srv = await startServer({ port: 0, host: '127.0.0.1', quiet: true });
browser = await puppeteer.launch({ executablePath: CHROME, headless: true, args: ['--no-first-run', '--force-device-scale-factor=1'] });
mkdirSync(OUT, { recursive: true });
});
after(async () => {
await browser?.close();
await srv?.close();
});
for (const board of ['2d', '3d']) {
test(`${board} board: grey out of the gate, orange from the warning, red once freed — each model as its sim form`, async (t) => {
const page = await browser.newPage();
const problems = [];
page.on('console', (m) => { if (m.type() === 'error') problems.push(`console: ${m.text()}`); });
page.on('pageerror', (e) => problems.push(`pageerror: ${e.message}`));
page.on('response', (r) => { if (r.status() >= 400) problems.push(`HTTP ${r.status()} ${r.url()}`); });
try {
await page.setViewport({ width: 1600, height: 900 });
await page.goto(`http://127.0.0.1:${srv.port}/dev/render-demo.html?scene=normal-m01&paused=1&panel=0&board=${board}`);
await page.waitForFunction('window.__demo && (window.__demo.ready || window.__demo.error)', { timeout: 40000 });
const on3d = await page.evaluate(() => !!window.__demo.view.stats().board3d?.on);
if (board === '3d' && !on3d) { t.skip('no 3D board here (local board art or WebGL2 missing)'); return; }
assert.equal(on3d, board === '3d', 'the board mode asked for');
await page.evaluate(async (spec) => {
const { loadBrowserSim } = await import('/js/battle/runner.js');
const { data } = await import('/js/data.js');
const { spec: S, ds } = await loadBrowserSim();
const b = S.createBattleFromSpec(spec, ds, { quiet: true });
const v = window.__demo.view;
v.setStage(data.lookup('stages', spec.stageId));
b.step();
const meta = b.fieldMeta();
v.enterBattle(meta);
v.setCamera('normal', { rect: meta.rect, side: 'L', instant: true });
v.setLocalFeed({ on: true, speed: 2 });
window.__pr = { b, v, meta, log: [] };
}, SPEC);
/** Step the sim `ticks` ticks, feeding the view; log each prisoner's sim form and drawn clip. */
const run = (ticks) => page.evaluate(async (ticks, keys) => {
const { b, v, meta, log } = window.__pr;
const raf = () => new Promise((r) => requestAnimationFrame(() => r()));
for (let i = 0; i < ticks; i++) {
b.step();
if (i % 3 !== 2) continue;
const ev = b.drainEvents();
if (ev.length) v.pushEvents({ t: 'b.ev', fieldId: meta.fieldId, gt: b.time, ev });
v.pushSnapshot(b.snapshot());
await raf();
for (const e of b.enemies) {
if (!keys.includes(e.defId) || !e.alive) continue;
const view = v.debug.views.get(e.id);
if (view?.spineReady) log.push({ t: +b.time.toFixed(2), key: e.defId, form: e.form ?? null, clip: view.actor?.current ?? null, attacks: e.stats.attacks });
}
}
return b.time;
}, ticks, KEYS);
/** Screenshot cropped to the prisoners' drawn bodies. */
const shot = async (name) => {
const r = await page.evaluate((keys) => {
const { b, v } = window.__pr;
const rects = b.enemies.filter((e) => keys.includes(e.defId) && e.alive).map((e) => v.debug.views.get(e.id)?.bounds()).filter(Boolean);
if (!rects.length) return null;
const x0 = Math.min(...rects.map((q) => q.x)), y0 = Math.min(...rects.map((q) => q.y));
const x1 = Math.max(...rects.map((q) => q.x + q.width)), y1 = Math.max(...rects.map((q) => q.y + q.height));
return { x: x0, y: y0, w: x1 - x0, h: y1 - y0 };
}, KEYS);
const pad = 60;
const clip = r ? { x: Math.max(0, r.x - pad), y: Math.max(0, r.y - pad), width: Math.min(1600, r.w + 2 * pad), height: Math.min(900, r.h + 2 * pad) } : undefined;
await page.screenshot({ path: path.join(OUT, `prisoners-${board}-${name}.png`), ...(clip ? { clip } : {}) });
};
await run(30 * 3);
await new Promise((r) => setTimeout(r, 2500)); // the Spine models load
await run(30 * 3);
await shot('confined');
// until 普通囚犯 shows its warning, then until every prisoner is freed
for (let k = 0; k < 20; k++) {
await run(30);
const lp = await page.evaluate(() => window.__pr.b.enemies.find((e) => e.defId === 'enemy_1116_liprr')?.form ?? null);
if (lp === 'warning') break;
}
await shot('warning');
for (let k = 0; k < 60; k++) {
await run(30);
const done = await page.evaluate((keys) => keys.every((key) => window.__pr.b.enemies.find((e) => e.defId === key)?.form === 'liberty'), KEYS);
if (done) break;
}
await run(30);
await shot('freed');
const log = await page.evaluate(() => window.__pr.log);
for (const key of KEYS) {
const rows = log.filter((x) => x.key === key && x.clip);
for (const [i, form] of [[0, null], [1, 'warning'], [2, 'liberty']]) {
// the view draws the sim's state a moment later (the render delay): rows within 1 s of the change are skipped
const first = rows.find((x) => x.form === form)?.t ?? Infinity;
const seen = rows.filter((x) => x.form === form && (form === null || x.t >= first + 1));
assert.ok(seen.length > 0, `${key}: drawn while its sim form is ${form ?? 'confined'}`);
const wrong = seen.filter((x) => setOf(key, x.clip) !== i);
assert.deepEqual(wrong.slice(0, 3), [], `${key} ${form ?? 'confined'}: the ${['grey', 'orange', 'red'][i]} set (${[...new Set(seen.map((x) => x.clip))]})`);
}
}
assert.deepEqual(problems, []);
} finally {
await page.close();
}
});
}
});
+117
View File
@@ -0,0 +1,117 @@
// test/render/feedback5-prisoners.test.js — community report of 2026-10-06 「囚徒类敌人出门就是已解放的模型」, client side.
// The 孤岛风云 prisoners' skeletons carry three clip sets whose collar light is grey, blinking orange and red; their
// official battle prefabs (local client battle/enm_pfb_6.ab: the Graphic component's anim key → clip table and the
// modes' replace pairs) draw 【禁锢】 on the grey set (the Spine starts on it), mode R — the warning before the last
// confined attack — on the orange set and 【解放】 (mode L) on the red one. The manifest's default roles used to pick
// 普通囚犯 / 老练囚犯's unnumbered set, the red one (tools/assets/spine.mjs PREFAB_SPINE_ROLES fixes it), and no FORMS entry
// existed, so no prisoner ever changed. The 3D board draws the same Pixi views over its canvas (render/board3d/scene.js),
// so one fix covers both boards. Headless fake PIXI (test/render/fakepixi.js); sim side:
// test/content/feedback5-prisoners.test.js.
// Run: node --test test/render/feedback5-prisoners.test.js
import { test, before, after } from 'node:test';
import assert from 'node:assert/strict';
import { readFileSync } from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { installFakePixi, fakeViewCtx } from './fakepixi.js';
import { presetCamera } from '../../public/js/render/projection.js';
import { ANIM } from '../../shared/constants.js';
import { fxSpec } from '../../public/js/render/fx/kinds.js';
import { resolveRoles } from '../../tools/assets/anim-roles.mjs';
import { PREFAB_SPINE_ROLES, applyRoleFix } from '../../tools/assets/spine.mjs';
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..');
const assets = JSON.parse(readFileSync(path.join(ROOT, 'data/assets.json'), 'utf8'));
/**
* The official prefabs' idle clip per mode (Default = confined / R = warning / L = liberty) and the clip-name suffix of
* that mode's Move / Attack / Die (read from battle/enm_pfb_6.ab; the light colours from the skeletons' slot colour
* timelines: 普通囚犯 Idle red / Idle2 orange / Idle3 grey, 强壮囚犯 Idle grey / Idle2 orange / Idle3 red).
*/
const OFFICIAL = {
enemy_1116_liprr: ['3', '2', ''],
enemy_1116_liprr_2: ['3', '2', ''],
enemy_1119_vofsd: ['', '2', '3'],
enemy_1118_lidbox_2: ['_grey', '_orange', '_red'],
enemy_1121_lifbos: ['_grey', '_orange', '_red'],
enemy_1121_lifbos_2: ['_grey', '_orange', '_red'],
};
let fake, UnitView, FORMS;
before(async () => {
fake = installFakePixi();
({ UnitView, FORMS } = await import('../../public/js/render/units.js'));
});
after(() => fake.restore());
const tick = () => new Promise((r) => setImmediate(r));
const cam = () => presetCamera('normal', { width: 1280, height: 720 });
function store(id) {
const entry = assets.enemies[id].spine;
const names = Object.keys(entry.animations || {});
return {
picture: () => null,
image: async () => null,
spineEntry: () => entry,
spine: { acquire: async () => ({ animations: names.map((name) => ({ name })) }), release() {} },
};
}
async function view(id, info = {}) {
const ctx = fakeViewCtx(fake.P, { assets: store(id), cam });
const v = new UnitView(ctx, { id: 7, side: 'enemy', kind: 'enemy', defId: id, spine: id, tier: 1, x: 8, y: 9, maxHp: 1000, facing: -1, ...info });
await tick(); await tick();
assert.ok(v.actor, `${id}: Spine model built`);
return v;
}
const sample = (anim = 0) => ({ x: 8, y: 9, hp: 1000, maxHp: 1000, sp: 0, spMax: 0, flags: 0, anim, vx: 0 });
test('the manifest draws every prisoner confined first (the official prefab\'s grey set), and FORMS holds its warning and liberty sets', () => {
for (const [id, [conf, warn, free]] of Object.entries(OFFICIAL)) {
const sp = assets.enemies[id].spine;
assert.equal(sp.anims.idle, `Idle${conf}`, `${id} idle`);
assert.equal(sp.anims.move.loop, `Move${conf}`, `${id} move`);
assert.equal(sp.anims.attack.loop, `Attack${conf}`, `${id} attack`);
assert.equal(sp.anims.die, `Die${conf}`, `${id} die`);
for (const [form, suf] of [['warning', warn], ['liberty', free]]) {
const r = FORMS[id]?.[form]?.roles;
assert.ok(r, `${id}: FORMS.${form}`);
assert.deepEqual([r.idle, r.move.loop, r.attack.loop, r.die], [`Idle${suf}`, `Move${suf}`, `Attack${suf}`, `Die${suf}`], `${id} ${form}`);
for (const n of [r.idle, r.move.loop, r.attack.loop, r.die]) assert.ok(n in sp.animations, `${id}: ${n} in the skeleton`);
assert.equal(FORMS[id][form].change, null, 'the prefab switches the set at once');
}
}
});
test('a prisoner view: confined clips, the orange set on \'warning\', the red set on \'liberty\'; a view built freed starts red', async () => {
for (const [id, [conf, warn, free]] of Object.entries(OFFICIAL)) {
const v = await view(id);
v.sync(sample(), 1);
assert.equal(v.actor.current, `Idle${conf}`, `${id} out of the gate`);
v.sync(sample(ANIM.MOVE), 2);
assert.equal(v.actor.current, `Move${conf}`, `${id} walking confined`);
v.setForm('warning');
assert.equal(v.actor.current, `Move${warn}`, `${id} warning`);
v.setForm('liberty');
assert.equal(v.actor.current, `Move${free}`, `${id} freed`);
v.sync(sample(), 3);
assert.equal(v.actor.current, `Idle${free}`, `${id} freed idle`);
const late = await view(id, { form: 'liberty' });
late.sync(sample(), 1);
assert.equal(late.actor.current, `Idle${free}`, `${id}: a view built after the liberation (UnitInfo form)`);
}
});
test('the warning fx draws nothing of its own (the blinking collar is the model\'s); the liberation keeps its white blast', () => {
assert.equal(fxSpec('phase', { kind: 'warning', form: 'warning' }).a, 'none');
assert.equal(fxSpec('liberate', { form: 'liberty' }).a, 'blast');
});
test('tools/assets/spine.mjs PREFAB_SPINE_ROLES: the committed manifest is what fetch-assets resolves for 普通囚犯 / 老练囚犯', () => {
for (const id of ['enemy_1116_liprr', 'enemy_1116_liprr_2']) {
const sp = assets.enemies[id].spine;
const out = applyRoleFix(resolveRoles(Object.keys(sp.animations), { skillIndices: [0], durations: sp.animations }), PREFAB_SPINE_ROLES[id], sp.animations);
assert.deepEqual(out.missing, []);
assert.deepEqual(out.roles, sp.anims, id);
}
});
+99
View File
@@ -0,0 +1,99 @@
// test/sim/feedback5-bounty-payee.test.js — community report of 2026-10-06 「被源石地板烫死的悬赏没给赏金」. The bounty pays
// whenever the body dies (the owner's decision, relayed 2026-10-06; 0.1.1 "a bounty coin is paid once, at the final
// death"; 0.1.3 §23.25 "Killing the body pays once"); PRTS 卫戍协议:盟约 决策: "该敌人于对应玩家所属区域倒下时,使相应玩家获得
// 额外资金". Battle._bountyPayee: an operator of a player in the battle that dealt the blow pays its player; any other
// death pays the card's owner when that player fights there — on its own field a 活性源石 death always paid (pinned) —
// and in 联防, where the owner is the leaker (unite.js planUnite) and fights elsewhere, the helper whose half it fell on.
// Until 0.2.0 that last case fell back to the leaker, who has no per-player entry in the 联防 battle: the coins were
// dropped (until 0.1.3 the 联防 field was the round's map — 战场#04's 活性源石 burned leaked bounty enemies for nothing).
// Run: node --test test/sim/feedback5-bounty-payee.test.js
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { makeBattle, enemyRec, chessRec, checkInvariants } from '../helpers/battleHarness.js';
const coins = (h) => {
const out = {};
for (const e of h.eventsOf('bounty')) out[e[1]] = (out[e[1]] || 0) + e[2];
return out;
};
const done = (h) => { checkInvariants(h.b); assert.equal(h.b.errors.length, 0, JSON.stringify(h.b.errors[0])); };
const helper = (playerId, seat, side, colOffset, units = []) => ({ playerId, seat, side, colOffset, units, bonds: {}, layers: {} });
// a 联防 field: helpers A (left half) and B (right half), a bounty enemy the leaker L sent in (planUnite's shape)
function unite(players, pos) {
return makeBattle({
kind: 'unite', content: 'none', autoFinish: false, timeLimit: 60, players,
defs: { enemies: { enemy_b: enemyRec({ key: 'enemy_b', hp: 100, speed: 0 }), enemy_x: enemyRec({ key: 'enemy_x', hp: 100, speed: 0 }) } },
enemies: [{ key: 'enemy_b', pos, sourcePlayerId: 'L', mods: { bountyId: 'card1' }, bounty: { coins: 2, ownerPlayerId: 'L' }, tag: 'bounty' }],
});
}
const target = (h) => h.b.enemies.find((e) => e.defId === 'enemy_b');
test('own field (战场#04): a bounty enemy the 活性源石 alone burns to death pays its owner — as before', () => {
const h = makeBattle({
stageId: 'act1autochess_m04', autoFinish: false, timeLimit: 60,
defs: { enemies: { enemy_b: enemyRec({ key: 'enemy_b', hp: 100, speed: 0.5 }) } },
enemies: [{ key: 'enemy_b', route: { motion: 'WALK', start: [10, 7], end: [9, 2], checkpoints: [] }, mods: { bountyId: 'card1' }, bounty: { coins: 2, ownerPlayerId: 'p1' }, tag: 'bounty', ownerPlayerId: 'p1' }],
});
assert.ok(h.runUntil(() => !h.b.enemies.some((e) => e.alive) && h.b.time > 1, 30));
assert.deepEqual(h.eventsOf('die').map((d) => d[2]), ['killed'], 'it died, no leak');
assert.deepEqual(coins(h), { p1: 2 });
assert.equal(h.result().perPlayer.p1.coins, 2);
done(h);
});
test('联防: a leaked bounty enemy that dies with no operator behind it pays the helper of the half it fell on', () => {
const ways = [
['killed by nobody', (h, e) => h.b.kill(e, null)],
['无来源 terrain-tagged damage', (h, e) => h.b.dealDamage(null, e, { amount: 500, type: 'true', canDodge: false, tags: ['terrain'] })],
['another enemy\'s hit', (h, e) => h.b.dealDamage(h.spawn('enemy_x', { pos: [10, 3] }), e, { amount: 500, type: 'true' })],
['its own HP loss', (h, e) => h.b.loseHp(e, 500, { source: e })],
];
for (const [label, how] of ways) {
// one helper: the whole field is hers
const h1 = unite([helper('A', 0, 'L', 0)], [10, 6]);
h1.step();
how(h1, target(h1));
assert.ok(!target(h1).alive, label);
assert.deepEqual(coins(h1), { A: 2 }, `one helper, ${label}`);
assert.equal(h1.result().perPlayer.A.coins, 2);
done(h1);
// two helpers: by the half it fell on (the right-hand helper's half from column 11)
for (const [col, who] of [[5, 'A'], [15, 'B']]) {
const h2 = unite([helper('A', 0, 'L', 0), helper('B', 1, 'R', 8)], [10, col]);
h2.step();
how(h2, target(h2));
assert.deepEqual(coins(h2), { [who]: 2 }, `two helpers, column ${col}, ${label}`);
done(h2);
}
}
});
test('联防: a helper\'s operator that knocks it out still takes the coins, whatever half it fell on', () => {
const GUN = chessRec({ id: 't_gun', profession: 'SNIPER', projectile: 'none', stats: { atk: 50, maxHp: 1e7, bat: 1, blockCnt: 0 }, rangeGrid: [[0, 0]], skill: null });
const h = makeBattle({
kind: 'unite', content: 'none', autoFinish: false, timeLimit: 60,
players: [helper('A', 0, 'L', 0, [{ uid: 1, kind: 'chess', chessId: 't_gun', row: 10, col: 4 }]), helper('B', 1, 'R', 8)],
defs: { chess: { t_gun: GUN }, enemies: { enemy_b: enemyRec({ key: 'enemy_b', hp: 100, speed: 0 }) } },
enemies: [{ key: 'enemy_b', pos: [10, 15], sourcePlayerId: 'L', mods: { bountyId: 'card1' }, bounty: { coins: 2, ownerPlayerId: 'L' }, tag: 'bounty' }],
});
h.step();
const gun = h.b.allies().find((u) => u.ownerId === 'A');
assert.ok(gun, 'A\'s operator');
h.b.dealDamage(gun, target(h), { amount: 500, type: 'phys' });
assert.deepEqual(coins(h), { A: 2 }, 'the killer\'s player, on B\'s half');
done(h);
});
test('Final Assault pair field: the card\'s owner fights there, so a death nobody caused pays the owner on either half', () => {
const h = makeBattle({
kind: 'boss', content: 'none', autoFinish: false, timeLimit: 60,
players: [helper('A', 0, 'L', 0), helper('B', 1, 'R', 8)],
defs: { enemies: { enemy_b: enemyRec({ key: 'enemy_b', hp: 100, speed: 0 }) } },
enemies: [{ key: 'enemy_b', pos: [3, 15], ownerPlayerId: 'A', mods: { bountyId: 'card1' }, bounty: { coins: 2, ownerPlayerId: 'A' }, tag: 'bounty' }],
});
h.step();
h.b.kill(target(h), null);
assert.deepEqual(coins(h), { A: 2 });
done(h);
});
+75
View File
@@ -0,0 +1,75 @@
// test/sim/feedback5-community-pins.test.js — two community reports of 2026-10-06 that this tree already answers, pinned
// (DESIGN §25.14; they pass on the parent commit — nothing changed for them):
// 「敌人在忍冬技能范围内没有开技能,在攻击范围才开」 — 0.1.4 cast her default S3 隐狐之艺 on its official DEFAULT row, i.e.
// only with an enemy in her 1-tile attack range; 0.2.0's ACTIVE_RANGE (the owner's decision of 2026-10-05, §25.5)
// casts it with an enemy inside its running range 2-2. S2 坠刃拷问 casts on anything in its 技能范围 3-12
// (SKILL_RANGE), S1 小施惩戒 (AUTO, no larger range) on her attack.
// 「悬赏敌人枯朽萃聚使徒召唤的枯朽之种被击杀也会获得赏金」 — the seeds come from spawnChildren, which drops the card's
// bountyId / bountyCoins (0.1.3 §23.25, GitHub #67 / #89-2); killing them never paid on the own field, and since 0.1.3
// a leaked seed no longer re-enters 联防 carrying the card (≤ 0.1.2 every one paid it again there).
// Run: node --test test/sim/feedback5-community-pins.test.js
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { makeBattle, enemyRec, checkInvariants } from '../helpers/battleHarness.js';
import { getDefaultSource } from '../../server/sim/simdata.js';
import { planUnite } from '../../server/match/unite.js';
const ds = getDefaultSource();
const done = (h) => { checkInvariants(h.b); assert.equal(h.b.errors.length, 0, JSON.stringify(h.b.errors[0])); };
const dummy = (key) => enemyRec({ key, hp: 1e9, speed: 0, mass: 0 });
test('忍冬: S3 casts with an enemy in its 2-2 running range (not only in her attack range), S2 on its 3-12, S1 on her attack', () => {
const casts = (id, skillId, pos) => {
const index = ds.rawChess(id).skills.find((s) => s.skillId === skillId).index;
const h = makeBattle({ seed: 3, autoFinish: false, timeLimit: 60, defs: { enemies: { e: dummy('e') } }, units: [{ chessId: id, row: 10, col: 4, skillIndex: index }] });
h.step();
const u = h.unit(id);
u.skill.gainSp(999, 'test');
h.spawn('e', { pos });
h.run(3);
done(h);
return u.skill.activations;
};
for (const id of ['chess_char_3_18_a', 'chess_char_3_18_b']) {
assert.deepEqual(ds.rawChess(id).rangeGrid, [[0, 0], [0, 1]], `${id}: her own range is 1 tile ahead`);
assert.ok(casts(id, 'skchr_vulpis_3', [10, 6]) >= 1, `${id} S3: an enemy 2 tiles ahead`);
assert.equal(casts(id, 'skchr_vulpis_3', [10, 7]), 0, `${id} S3: not 3 tiles ahead`);
for (const pos of [[10, 6], [10, 7], [9, 5]]) assert.equal(casts(id, 'skchr_vulpis_2', pos), 1, `${id} S2 (3-12): ${pos}`);
assert.equal(casts(id, 'skchr_vulpis_1', [10, 6]), 0, `${id} S1: not out of her attack range`);
assert.ok(casts(id, 'skchr_vulpis_1', [10, 5]) >= 1, `${id} S1: on her attack`);
}
});
test('枯朽萃聚使徒 as a bounty: its 枯朽之种 carry no bounty and pay nothing; the body pays once; in 联防 only its own leak carries the card', () => {
const card = { id: 'enemyeffect_10_8', card: { payout: 'kill', coin: 2, enemyKey: 'enemy_1321_wdarft' } };
const h = makeBattle({
autoFinish: false, timeLimit: 200,
enemies: [{ key: 'enemy_1321_wdarft', route: 2, mods: { hpMul: 1, bountyId: card.id }, bounty: { coins: 2, ownerPlayerId: 'p1' }, tag: 'bounty', ownerPlayerId: 'p1' }],
});
assert.ok(h.runUntil(() => h.b.enemies.some((e) => e.alive && e.defId === 'enemy_1269_nhfly'), 30), 'BornBugs cast');
const seeds = h.b.enemies.filter((e) => e.alive && e.defId === 'enemy_1269_nhfly');
for (const s of seeds) {
assert.equal(s.bounty, null);
assert.ok(!s.mods || (s.mods.bountyId == null && s.mods.bountyCoins == null));
h.b.kill(s, null);
}
assert.deepEqual(h.eventsOf('bounty'), [], 'the seeds pay nothing');
h.b.kill(h.enemy('enemy_1321_wdarft'), null);
assert.deepEqual(h.eventsOf('bounty'), [['bounty', 'p1', 2]], 'the body pays once');
done(h);
// 联防: the 使徒 and its seeds leak (no operator); only the 使徒 re-enters with the card's bounty
const h2 = makeBattle({
autoFinish: true, timeLimit: 200,
enemies: [{ key: 'enemy_1321_wdarft', route: 2, mods: { hpMul: 1, bountyId: card.id }, bounty: { coins: 2, ownerPlayerId: 'p1' }, tag: 'bounty', ownerPlayerId: 'p1' }],
});
h2.runToEnd(200);
const r = h2.result().perPlayer.p1;
assert.ok(r.leaked.filter((l) => l.enemyKey === 'enemy_1269_nhfly').length >= 3, 'seeds leaked');
const seat = (id, s, o = {}) => ({ playerId: id, seat: s, deployCount: o.deployCount ?? 1, bonds: {}, layers: {}, board: new Map(), bounties: o.bounties ?? [] });
const leaker = seat('p1', 1, { bounties: [card] });
const helperSeat = seat('H', 0, { deployCount: 3 });
const m = { isSolo: false, alivePlayers: () => [leaker, helperSeat], gd: { unite: { maxHelpers: 2 }, enemy: (k) => ({ key: k }) } };
const plan = planUnite(m, new Map([['p1', r], ['H', { perfect: true, leaked: [], unitsEnd: [] }]]));
assert.deepEqual(plan.leaked.filter((l) => l.bounty).map((l) => [l.enemyKey, l.bounty.coins]), [['enemy_1321_wdarft', 2]]);
});
+29 -2
View File
@@ -107,8 +107,32 @@ export const LOCAL_SPINE_ROLES = Object.freeze({
},
});
/** The confined clips of 普通囚犯 / 老练囚犯: their grey *3 set (PREFAB_SPINE_ROLES). */
const PRISONER_GREY_3 = Object.freeze({
idle: 'Idle3', deploy: 'Idle3', attack: clipOf('Attack3'), skill: { ...clipOf('Attack3', 'attack'), index: 0, idle: null },
die: 'Die3', move: clipOf('Move3'),
});
/**
* `roles` with the fix of LOCAL_SPINE_ROLES applied: each fixed role whose clips all exist in `durations` replaces the
* Role fixes of web enemy models from their official battle prefabs, for skeletons whose clip names mislead the resolver
* (by name): model id → roles replacing the resolved ones (the others are kept); processModels applies them, so
* data/assets.json carries them. A fix naming a clip the skeleton lacks is dropped and reported. Source: the prefab's
* animation table (its Graphic component: anim key → clip) and the clip its Spine starts on, read from the local client's
* battle/enm_pfb_*.ab (tools/local-extract, UnityPy).
* - 普通囚犯 / 老练囚犯 (enemy_1116_liprr / _2, 孤岛风云 prisoners): three clip sets whose collar light is red (Idle, Move …),
* blinking orange (Idle2 …) and grey (Idle3 …). The prefab maps its keys Idle / Move / Attack / Die to the grey *3 set
* and starts on Default3 — mode Default, 【禁锢】 —, the orange *2 set is its mode R (the warning before the last
* confined attack) and the red unnumbered set its mode L, 【解放】. The resolver took the unnumbered set, so they came out
* of the gate already freed (community report of 2026-10-06). The other prisoners' names already resolve to their grey
* set (强壮囚犯's Idle is its grey one; 拳师囚犯 / 重犯 / 传奇重犯 *_grey); every prisoner's later sets are the render/units.js
* FORMS 'warning' / 'liberty' the sim switches to (content/enemies/archetypes.js prisoner).
*/
export const PREFAB_SPINE_ROLES = Object.freeze({
enemy_1116_liprr: PRISONER_GREY_3,
enemy_1116_liprr_2: PRISONER_GREY_3,
});
/**
* `roles` with the fix of LOCAL_SPINE_ROLES / PREFAB_SPINE_ROLES applied: each fixed role whose clips all exist in `durations` replaces the
* resolved one; `missing` lists the roles left as resolved because a clip is missing.
* @param {any} roles resolveRoles output
* @param {Record<string, any>|undefined} fix
@@ -293,7 +317,10 @@ export async function processModels(models, { root, dl, cachePath, download = tr
nextCache[m.skel.rel] = { key: ck, info: sk };
if (sk.missingRegions?.length) problems.push(`${m.key}: ${sk.missingRegions.length} attachment(s) not in atlas (e.g. ${sk.missingRegions[0]})`);
if (!sk.animations.length) { problems.push(`${m.key}: skeleton has no animations`); continue; }
const anims = resolveRoles(sk.animations, { skillIndices: m.skillIndices, durations: sk.durations });
const id = String(m.key).startsWith('enemy:') ? String(m.key).slice('enemy:'.length) : null;
const fixed = applyRoleFix(resolveRoles(sk.animations, { skillIndices: m.skillIndices, durations: sk.durations }), id ? PREFAB_SPINE_ROLES[id] : undefined, sk.durations);
if (fixed.missing.length) problems.push(`${m.key}: role fix not applied (clip missing) for ${fixed.missing.join(', ')}`);
const anims = fixed.roles;
entries.set(m.key, {
skel: assetUrl(m.skel.rel),
atlas: assetUrl(m.atlas.rel),