feedback5: merge CB3 — community reports (operator kits): 砾's normal attack hits twice at 50 % 伤害倍率 (a 频次 enemy loses 2), 乌尔比安's S3 moves only onto his own board (never behind the one-helper 联防 map's red gate nor onto a boss field's other half), the 「受到攻击时」 counters answer every enemy damage instance (菲莱 S2 on 深溟巢涌者's pulse, 星熊, 泡泡, 刺玫, 余, 玛恩纳, 年, 斩业星熊), an in-place 复活 restarts a deploy-timed skill so a 突袭 member jumps at once, 银灰's normal attack plays its own impact (and 雷蛇 / 初雪 / 圣约送葬人 drop a skill mode's sound); five reports pinned; §25.17 between CB2's §25.16 and CB4's §25.18; data/assets.json lists 银灰's impact (p_imp_spear_n.mp3 fetched); golden: vs feedback5 CB3's own rules — roster-002/004/005/008/010/012/016/024/033/044, bond-indomShip-low/high, bond-kazimierzShip-low/high, bond-lateranoShip-low, boss-boss_2-solo, boss-boss_4-pair/-solo, hidden-boss_8-pair/-solo, hidden-boss_9-solo, diy-051, matches solo-FUNNY-2, coop2-NORMAL-3, coop4-ABYSS-7, coop2-ABYSS-10-boosted; vs CB3 exactly what feedback5 changed since its base (CB2, CB4, CB5)
The merge:
- server/sim/battle/players.js: CB3's onOwnBoard hunk is byte-identical to CB4's (git kept one); its comment and
docs/SIM.md's onOwnBoard row now name 乌尔比安's S3 【移动】 next to the 突袭 landing (DESIGN §25.17.2 / §25.18).
- test/sim/facing-invariance.test.js: CB3's scenario setup (onOwnBoard off on the open field) and the CB4 merge's
突袭 test (its enemy inside the board) merged cleanly, both kept.
- data/assets.json: CB3 had regenerated it offline without 银灰's entry (his official impact file was not on disk);
`node tools/fetch-assets.mjs --add-only` (shared public/assets, add-only) downloaded p_imp_spear_n.mp3 — 8.8 KB,
the only new file (ok 1, skipped 7968; the 117 misses are the known upstream gaps) — and rewrote the manifest.
Field-wise JSON compare with CB3's manifest: only audio.sfx.units.char_172_svrash = { hit: p_imp_spear_n } plus hash
and stats (files / bytes / sfxUnits +1); against feedback5: CB3's four operators (银灰 now the spear impact and no
S3 swing, 雷蛇 / 初雪 / 圣约送葬人 without the skill-mode impact) plus hash / stats. §25.17.6 says so.
- docs/history/0.2.0.md: §25.17 placed in order, the intro's per-stream list and workstream list name CB3.
Golden moves outside CB3's commit list: coop2-NORMAL-3 fields 砾 from round 3 (her double hit) and 刺玫 in rounds 4-7
(instrumented); solo-FUNNY-1 (in CB3's list through the counters) fields no counter operator on feedback5's path, only
砾, whose two half hits change no kill, leak, LP or end stat there, so its digest stays.
Gate: non-browser suites 5003 / 5003, npm run golden ok, test/golden.test.js 9 / 9, lint 0 errors, check:imports ok,
typecheck ok.
This commit is contained in:
commit
d841d6ac22
33 files changed
+956
-245
No files matched your search
+1
-1
@@ -1 +1 @@
|
||||
{"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
|
||||
{"version":1,"hash":"c79a28fbd507","generator":"tools/fetch-assets.mjs","stats":{"files":7969,"bytes":485061859,"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
|
||||
+4
-1
@@ -206,7 +206,10 @@ All paths are URL paths relative to the site root, for example `/assets/char/ava
|
||||
// units' attack / hit (tools/assets/audio.mjs pickUnitSfx): operators get normal-mode banks only — the plain
|
||||
// `attack` / `combat` ability first, never a bank holding a skill-mode file (`_d` / `_h` / `_s`; the normal attack's end
|
||||
// in `_n`) — with their own projectile banks (ON_PROJECTILE_BORN / _HIT.projectile_chr_<name>) as fallbacks
|
||||
// (DESIGN §18.4: 纯烬艾雅法拉's S3 impact used to be her `hit`); enemies and tokens take the first attack-like bank
|
||||
// (DESIGN §18.4: 纯烬艾雅法拉's S3 impact used to be her `hit`); an operator with such a plain bank (its default mode is
|
||||
// the unsuffixed ability) never takes a numbered variant `attack.N` — a skill mode's, whatever its file name (银灰's S3
|
||||
// swing p_atk_silver_n, community report of 2026-10-06); one that numbers its default mode (`attack.0` …) keeps the
|
||||
// numbered order; enemies and tokens take the first attack-like bank
|
||||
fonts: { css: '/fonts/fonts.css', faces: { [name]: { family, weight, woff2?, original } } }
|
||||
}
|
||||
```
|
||||
|
||||
+9
-4
@@ -779,7 +779,7 @@ registration order. `battle.off(handle)` / `battle.off(name, fn)` / `battle.offO
|
||||
| `damaged` | `{ source, target, amount, type, dmg, credit }` | after application (`amount` may be 0 when shielded); element fills too (with their source); 无来源: `source` null, `credit` set |
|
||||
| `hpDamage` | `{ source, target, amount, dmg, credit }` | a damage instance after shields, before the HP loss (§4; not a 流失): lower `amount` only (a raise is ignored) — HP floors / reductions ordered after a barrier (kits/ops/op-huang.js, op-zuole.js) |
|
||||
| `heal` | `{ source, target, amount, opts }` | mutable `amount` |
|
||||
| `fatal` | `{ unit, source, credit, dmg, amount, prevented }` | HP would reach 0 — set `prevented` (substitutes, kit savers, 不死 / 复活 items, 埃芒加德; 不屈 is a `death` hook). Fired by every HP loss of a unit without a boss pool — hits of any type, element bursts, 无来源 damage, `loseHp` 流失. Order: kits' own savers (10 … −60) → items' 不死 (坚固维式重锤 — once per deployment: `items/battle.js deploymentOf`, a key every deploy changes and an in-place 复活 changes too; one battle-level hook holds the running windows (`holdsUndying`), so a window outlasts a lend, DESIGN §21.21 — the lock `PRIO_REVIVE` −100 after the substitutes (−100, registered first), the running windows `PRIO_UNDYING_HELD` −99 before them: a 傀儡师 holding 不死 does not switch, PRTS 分支特性信息 傀儡师 "未持有不死的情况下", DESIGN §22.11) → 淬羽赫默 S3's 不死 (−100.5: PRTS 衍生生命 "无畏者协议提供的不死效果仅在目标没有不死效果时才会触发"; its running windows held at −99 like the hammer's) → items' 复活 (M3茧甲, `PRIO_RESPAWN` −101: PRTS "复活" acts on a knock-out, which a 不死 prevents) → 埃芒加德 (−110); both 复活 revive in place and call `revivedInPlace` (a new deployment for the lock) |
|
||||
| `fatal` | `{ unit, source, credit, dmg, amount, prevented }` | HP would reach 0 — set `prevented` (substitutes, kit savers, 不死 / 复活 items, 埃芒加德; 不屈 is a `death` hook). Fired by every HP loss of a unit without a boss pool — hits of any type, element bursts, 无来源 damage, `loseHp` 流失. Order: kits' own savers (10 … −60) → items' 不死 (坚固维式重锤 — once per deployment: `items/battle.js deploymentOf`, a key every deploy changes and an in-place 复活 changes too; one battle-level hook holds the running windows (`holdsUndying`), so a window outlasts a lend, DESIGN §21.21 — the lock `PRIO_REVIVE` −100 after the substitutes (−100, registered first), the running windows `PRIO_UNDYING_HELD` −99 before them: a 傀儡师 holding 不死 does not switch, PRTS 分支特性信息 傀儡师 "未持有不死的情况下", DESIGN §22.11) → 淬羽赫默 S3's 不死 (−100.5: PRTS 衍生生命 "无畏者协议提供的不死效果仅在目标没有不死效果时才会触发"; its running windows held at −99 like the hammer's) → items' 复活 (M3茧甲, `PRIO_RESPAWN` −101: PRTS "复活" acts on a knock-out, which a 不死 prevents) → 埃芒加德 (−110); both 复活 revive in place and call `revivedInPlace` (a new deployment for the lock, and a deploy-timed skill — `activateOnDeploy` — runs again from the next tick: started anew, or its window back to full; PRTS's 复活 is 退场 + a 0-time / 0-cost redeploy) |
|
||||
| `dollSwitch` | `{ unit, reason, done }` | content switches a 傀儡师 to its <替身> now (归溟幽灵鲨 S2 "技能结束后立刻切换为<替身>": no lethal HP loss); its trait does it unless it already is one or is not on the field, and sets `done` |
|
||||
| `dollSwap` | `{ unit, form }` | a 傀儡师 starts a switch — to its <替身> (`form` `'doll'`) or back to its <本体> (`null`); not when it is knocked out as the 替身 (不屈 rolls on it: "切换<替身>与<本体>时") |
|
||||
| `kill` | `{ killer, victim }` | victim HP reached 0 (a handler may revive by restoring HP) |
|
||||
@@ -803,7 +803,10 @@ registration order. `battle.off(handle)` / `battle.off(name, fn)` / `battle.offO
|
||||
"bonus damage on hit") must not react to its own output or to other reactive damage, or two such effects ping-pong
|
||||
until the nesting guard trips (the guard then skips *every* nested handler, including `kill`/`death` bookkeeping of
|
||||
content). Respond only to `dmg.isAttack` (normal attacks), tag your damage (`tags: ['counter']`) and skip tagged damage,
|
||||
or guard with a per-unit flag while dealing it. When the guard trips, the logged error names the open frames
|
||||
or guard with a per-unit flag while dealing it. The "受到攻击时" counters take the second way: the official ones fire on
|
||||
every damage instance from an enemy (ON_TAKE_DAMAGE — its attack, a skill hit, 深溟巢涌者's pulse; never a 流失), so they
|
||||
answer `kits/shared/tier1.js byEnemyAttack` (星熊 S2, 泡泡, 刺玫 S2, 余 S1, 玛恩纳 无动于衷, 年 S2, 斩业星熊; 菲莱 S2 any
|
||||
instance) and skip `'counter'` / `'reflect'` damage. When the guard trips, the logged error names the open frames
|
||||
(`chain: hit(enemy_x→chess_y) > damaged(chess_y) > …`).
|
||||
|
||||
---
|
||||
@@ -831,7 +834,7 @@ or guard with a per-unit flag while dealing it. When the guard trips, the logged
|
||||
| `addLayers(playerId, bondId, n, reason, {source})`, `addCoins(playerId, n)` | layers are a no-op when `flags.layerGainsEnabled` is false (unite/boss); a gain adds at most the room left under `BOND_LAYER_CAP` (999, shared/constants.js `layerGainRoom`: the client's `AddBondCount` min(L + n, 999)) on the live copy — or, without one, on the battle's own gains — and returns what it added (0 at the cap: no hook, no event) |
|
||||
| `getPlayer(playerId)` | `{ playerId, seat, side, colOffset, mirror, dir (default unit direction: RIGHT, mirrored side LEFT), facing (its sign), bonds (live copy, layers updated by addLayers), bandId, playerEffects, lpForBoss, dp, units }` |
|
||||
| `mapTile(ps, row, col, abs?)` / `mapDir(ps, dir, abs?)` | board → field tile / direction of a player (the FA right-side mirror) |
|
||||
| `onOwnBoard(ps, r, c)` | whether a field tile lies on the player's own board — GEO.FIELD (rows 9–12, cols 2–10) mapped onto this field: the 联防 right-hand helper's +8 columns, the boss field's rows 2–5 (never its hand / 临时整备区 rows 0–1), the mirrored right half; the 突袭 landing takes only such tiles (DESIGN §25.18) |
|
||||
| `onOwnBoard(ps, r, c)` | whether a field tile lies on the player's own board — GEO.FIELD (rows 9–12, cols 2–10) mapped onto this field: the 联防 right-hand helper's +8 columns, the boss field's rows 2–5 (never its hand / 临时整备区 rows 0–1), the mirrored right half; the 突袭 landing takes only such tiles (DESIGN §25.18), and so does 乌尔比安's S3 【移动】 (DESIGN §25.17.2) |
|
||||
| `addDp(playerId, n)`, `retreat(unit, {reason, permanent, dying})`, `relocate(unit, r, c)` | `relocate` only changes the tile (state kept, no event) |
|
||||
| `moveRedeploy(unit, r, c, { clearSp })` | a 【移动】 (PRTS 术语释义: "不退场,以当前血量在目标位置部署", a special retreat + redeploy): `relocate`'s checks (false = refused, nothing changed), then a new deployment (`deploySeq` / `aggroSeq` / `deployedAt`) and `deploy {initial:false, move:true}` (deploy effects fire again); no `die` / `death`, timer or cost (不屈 / 阿戈尔's revive never see it); HP, buffs and a running skill are kept (owner's deviation, DESIGN §22.3); `clearSp` empties the SP before the deploy handlers run — 乌尔比安 S3's move (kits/ops/chess_char_5_05-ulpia.js) and 【返回】 (`clearSp`; also the 从不混淆的方向 fallback, content/tokens.js) |
|
||||
| `redeploy(unit, { free=true, tile, keepSp })` | immediate (re)deployment of a dead/retreated ally (full HP, `deploy {initial:false}`); `free: false` pays `base.cost` DP (refused without it); without `tile` it lands on the unit's rest tile (`restTile`: where a knocked-out operator lies, else home); `tile: [r, c]` lands on that tile once (home unchanged; refused when off-rect, occupied or a knocked-out operator's tile, no fallback); `keepSp` keeps SP/charges (保留技力), restored before `deploy` fires — 突袭 raids, 阿戈尔 / 不屈 revives where the unit lies |
|
||||
@@ -1214,7 +1217,9 @@ S3 未照耀的荣光 — its CUSTOM_RANGE trigger also counts flyers). A stun /
|
||||
3.75 back = `BOOMERANG_RETURN_SPEED`, PRTS 跃跃; droneBomb 5 = 暴鸰's bomb, the official projectile_bombd); melee/`none` hits are
|
||||
instant, and so are `'beam'` hits (a 锁定攻击范围 AoE without a projectile — `rangeAoe` profiles: "在攻击前摇结束时选取范围内的全体目标,同时造成伤害", PRTS 作战机制). Kit-settable profile flags beyond the
|
||||
table: `hitSleep` (targets and damages sleeping enemies — "可以攻击沉睡的敌人"), `onEachHit(b, u, victim, hctx)`, `dmgMul`,
|
||||
`afterHit`, `afterAttack`, `canAttack`, `hitsFn(b, u, info)`, `storeEnergy` / `releaseEnergy` (the 秘术师 store, below), `priority` (targeting.js PRIORITY_FNS — `'heaviest'`: the 攻城手 trait
|
||||
`afterHit`, `afterAttack`, `canAttack`, `hitsFn(b, u, info)`, `hitDmgMul` (the 伤害倍率 of each of the `hits` instances on the
|
||||
main target — DamageInfo `mul`, after DEF / RES; the later instances give no 受击回复: 砾's two 50 % hits, PRTS 砾 特性备注),
|
||||
`storeEnergy` / `releaseEnergy` (the 秘术师 store, below), `priority` (targeting.js PRIORITY_FNS — `'heaviest'`: the 攻城手 trait
|
||||
"优先攻击重量最重的敌人", the highest current 重量等级 first: 早露 / 提丰; `'elite'`: "优先攻击精英或领袖敌人", an ELITE / BOSS
|
||||
rank enemy or a leader first: 薇薇安娜 S3), `blockFly`, `noHeal`, `skipEnemy(e)` (an enemy the unit never
|
||||
selects — its attacks, the enemies it blocks and its skill-trigger targets: targeting.js canTargetEnemy; 嵯峨 "不攻击重伤
|
||||
|
||||
@@ -100,7 +100,7 @@ Base stats (from data): `maxHp, atk, def, res` (0–100), `aspd` (100 base), `ba
|
||||
| `hit` | `{ source, target, dmg }` | before mitigation; mutate `dmg` (DamageInfo) |
|
||||
| `damaged` | `{ source, target, amount, type, dmg }` | after application |
|
||||
| `heal` | `{ source, target, amount }` | before application (mutable amount) |
|
||||
| `fatal` | `{ unit, source, credit, dmg, amount, prevented }` | HP would reach 0 — fired by every HP loss of a unit without a boss pool (hits of any type, element bursts, 无来源 damage, `loseHp`); set `prevented`. Order: kits' own savers (10 … −60) → items' 不死 (坚固维式重锤, once per deployment) `PRIO_REVIVE` −100 → items' 复活 (M3茧甲) `PRIO_RESPAWN` −101 → 埃芒加德 −110; the two 复活 revive in place and open a new deployment for the lock (§21.21); a running 坚固 window's hook sits at `PRIO_UNDYING_HELD` −99, before a 傀儡师's switch to its 替身 (−100, ahead of the lock — a 本体 holding 不死 does not switch, §22.11) |
|
||||
| `fatal` | `{ unit, source, credit, dmg, amount, prevented }` | HP would reach 0 — fired by every HP loss of a unit without a boss pool (hits of any type, element bursts, 无来源 damage, `loseHp`); set `prevented`. Order: kits' own savers (10 … −60) → items' 不死 (坚固维式重锤, once per deployment) `PRIO_REVIVE` −100 → items' 复活 (M3茧甲) `PRIO_RESPAWN` −101 → 埃芒加德 −110; the two 复活 revive in place and open a new deployment for the lock (§21.21) and for a deploy-timed skill (`activateOnDeploy`, started again: §25.17.5); a running 坚固 window's hook sits at `PRIO_UNDYING_HELD` −99, before a 傀儡师's switch to its 替身 (−100, ahead of the lock — a 本体 holding 不死 does not switch, §22.11) |
|
||||
| `kill` | `{ killer, victim }` | victim hp reached 0; a `killed` ability that keeps the enemy alive (a knock-out into a 重生 / form change, §21.4) hides it from every later handler, the kill count, credit and the bounty |
|
||||
| `death` | `{ unit }` | unit removed (ops may redeploy later); the `die` event and the death hooks fire only on removal |
|
||||
| `skillStart` / `skillEnd` | `{ unit, skill }` | |
|
||||
|
||||
+137
-5
@@ -10,7 +10,7 @@ after review with its golden scenarios named: R1–R6 (refactor, tooling), W5A (
|
||||
K1–K3 / W5N (补位), W5H / W5K / O1–O24 (自选编队 and its operator kits), W5I / W5S (languages, phases 1 and 2), W5C /
|
||||
W5E / W5F / W5J / W5L (fidelity, wave 1), WE1 / WE2 (the follow-ups the kit waves reported), W5M, W5R and the feedback4
|
||||
merges (the 0.1.4 ports), W5V (the owner's items of 2026-10-06), W5U (packaging), W5T (the docs), W5Y (round 18:
|
||||
three GitHub issues and three community PRs), W5AA and CB2 / CB4 / CB5 (the community reports of 2026-10-06), W5AC
|
||||
three GitHub issues and three community PRs), W5AA and CB2 / CB3 / CB4 / CB5 (the community reports of 2026-10-06), W5AC
|
||||
(rebindable shortcuts) and W5AD (language packs). Each rule was checked against the official data and PRTS; anything no
|
||||
source backs is marked [ASSUMED].
|
||||
The normative sections were rewritten with the streams: §0 (the DIY slots), §2 (the layout), §5.5 (the enemy damage
|
||||
@@ -31,10 +31,13 @@ bounty burned to death by the 活性源石, 枯朽之种 paying a bounty) → §
|
||||
second batch of community reports of 2026-10-06, one section per stream: CB2, healers, summons, timers (刺玫's S2 heals,
|
||||
琳琅诗怀雅 healing herself and her 破财消灾 cost after a redeploy, 赫默's drone at full SP, the countdown summons' 无敌 /
|
||||
禁疗 / timer bar, stacked alchemy zones; the chain heal, DoT damage, 伺夜's 狼影 and the 吟游者 trait answered) → §25.16;
|
||||
CB4, enemies, bosses, waves, movement (the 突袭 landing on the 临时整备区 row and the other half of the 联防 map, a
|
||||
silenced 萨卡兹枯朽战士's death pollution, 萨卡兹穿刺手's speed after a stun and its first hit, 自制投石机 blocked on the
|
||||
排气格栅; the briefing types' 7–9 waves, 新硎's 断刃, a freed prisoner in 联防 and 鸭爵's two swaps in one wave already
|
||||
answered; the moving leaders' routes checked; 野鬃, 锏's pulls, 昆图斯's footprint and the leaders' attack rate not
|
||||
CB3, operator kits and triggers (砾's double hit, 乌尔比安's S3 landing behind the 联防 red gate, the 「受到攻击时」
|
||||
counters on every enemy damage instance, a 突袭 member's jump after an in-place 复活, 银灰's sound; 铃兰's trigger,
|
||||
琳琅诗怀雅's champagne, the 突袭 玛恩纳, 归溟幽灵鲨 devoured and 荒芜拉普兰德 / 叙拉古 already answered; 乌尔比安's revive
|
||||
tile a question) → §25.17; CB4, enemies, bosses, waves, movement (the 突袭 landing on the 临时整备区 row and the
|
||||
other half of the 联防 map, a silenced 萨卡兹枯朽战士's death pollution, 萨卡兹穿刺手's speed after a stun and its first
|
||||
hit, 自制投石机 blocked on the 排气格栅; the briefing types' 7–9 waves, 新硎's 断刃, a freed prisoner in 联防 and 鸭爵's two
|
||||
swaps in one wave already answered; the moving leaders' routes checked; 野鬃, 锏's pulls, 昆图斯's footprint and the leaders' attack rate not
|
||||
reproduced) → §25.18; CB5, match flow and UI (a module's 特性追加 line after the class trait, the new shop slot filled at
|
||||
the upgrade, an eliminated player following a player through every round, the boss field and its leader in a watcher's
|
||||
boss prep, the pair together in the boss prep with the official green frames; PRs #189 / #191 reused, not merged; the
|
||||
@@ -1204,6 +1207,135 @@ the evidence.
|
||||
under 魔王 (pinned by `test/content/feedback5-regen.test.js`); 孤立 units stay out (PRTS 孤立). The countdown summons
|
||||
cannot be refilled since §25.16.5.
|
||||
|
||||
### 25.17 Community reports of 2026-10-06, stream CB3: operator kits and triggers — `sim/ai.js resolveHit` (`hitDmgMul`), `kits/ops/chess_char_2_12-gravel.js`, `kits/ops/chess_char_5_05-ulpia.js`, `sim/battle/players.js onOwnBoard`, `kits/shared/tier1.js byEnemyAttack`, `content/items/battle.js revivedInPlace`, `tools/assets/audio.mjs pickUnitSfx`
|
||||
|
||||
The owner's second collection of community reports (2026-10-06/07) was split over five streams; CB3 took the items about
|
||||
operator kits and skill triggers (items 2, 16.1, 16.4, 16.5, 17, 27, 28, 30, 44, 46, 54 of the list). Each was reproduced
|
||||
on the 0.2.0 tree with a script first (where the report could be older, on the v0.1.1–v0.1.4 sources too), then checked
|
||||
against the official data (character_table, skill_table, activity_table → act2autochess, audio_data, ArknightsGameData's
|
||||
buff templates, the local client's charpacks and skill prefabs) and PRTS (备注 included). Five are real and fixed, one
|
||||
commit each with its golden scenarios named; five were already answered or are not bugs (pinned by tests); one is a
|
||||
question for the owner.
|
||||
|
||||
#### 25.17.1 「砾的平A是比较特殊的双判,是两次50%伤害倍率(不是攻击倍率)」 (item 16.5): two instances of 50 % 伤害倍率 per normal attack — `sim/ai.js resolveHit`, `sim/professions.js` (`hitDmgMul`), `kits/ops/chess_char_2_12-gravel.js`
|
||||
|
||||
- **Seen**: one damage instance per attack (measured: against DEF 300, ATK 352, one hit of 52), so a 频次 enemy lost 1.
|
||||
- **Official**: PRTS 砾 特性备注 — in her attack animation every normal attack deals two instances, each 50 % of the final
|
||||
damage (after DEF / damage reduction, before 重设伤害), and the second triggers no 受击回复.
|
||||
- **Now**: the profile field `hitDmgMul` — the DamageInfo `mul` of each of the `hits` instances on the main target, applied
|
||||
after DEF / RES and the damage multipliers, `noSp` on the later ones — and 砾's kit trait `{ hits: 2, hitDmgMul: 0.5 }`:
|
||||
two hits of 26 in the example (the same total), 2 per attack against a 频次 enemy. Both her skills are passive, so every
|
||||
attack she makes is a normal attack.
|
||||
- [ASSUMED]: the two instances land at once, at her attack's damage frame (the animation's second hit is not timed).
|
||||
- Golden: 7 scenarios with 砾 on the board — roster-004 / 005 / 024, bond-indomShip-low / -high, bond-kazimierzShip-low /
|
||||
-high (two damage events per attack; in roster-024 and bond-kazimierzShip-high the last blow lands on another instance,
|
||||
so kills move between her and her neighbours). Tests: `test/sim/feedback5-gravel-double-hit.test.js`. Docs: docs/SIM.md.
|
||||
|
||||
#### 25.17.2 「乌尔比安使用3技能会在联防阶段跳到红门后」 (item 27): the S3 【移动】 lands only on his own board — `kits/ops/chess_char_5_05-ulpia.js`, `sim/battle/players.js onOwnBoard`
|
||||
|
||||
- **Seen**: on the one-helper 联防 map (act1autochess_escaped_single: the lone helper on the left half, the enemies out of
|
||||
the middle gate at col 10) an anchor that met no enemy flew on 6 tiles into the right half, where no enemy walks, and he
|
||||
stood there behind the red gate for the whole skill (reproduced: (10,7) → (10,13); on a solo boss field (2,5) → (2,11)).
|
||||
- **Official**: PRTS 乌尔比安 S3 备注 ③ — the anchor tile if it can be deployed on, else the tile one beyond, else his own
|
||||
tile. "可部署" is a tile his player deploys on.
|
||||
- **Cause**: "deployable" was any standable tile of the battle rect; UNITE_RECT spans both halves of the 联防 map and
|
||||
BOSS_RECT the hand / 临时整备区 rows and the partner's half.
|
||||
- **Now**: the landing must also lie on his board — `Battle.onOwnBoard(ps, r, c)`, the board region GEO.FIELD mapped onto
|
||||
the field as `mapTile` maps the pieces (the helper stream CB4 adds for the 突袭 landing; the hunk is identical).
|
||||
The anchor still flies its 6 tiles and blasts there; he stays when neither tile is his.
|
||||
- [ASSUMED]: that the official "可部署" excludes the other half of a shared field (the level files mark both halves
|
||||
buildable; no player deploys on the other's).
|
||||
- Golden: 1 scenario — fields hidden-boss_9-solo (his first cast landed on the right half). Tests:
|
||||
`test/sim/feedback5-ulpia-own-board.test.js`; `test/sim/facing-invariance.test.js` counts every tile of its open field
|
||||
as the player's own (a board-position rule, like the deployment order it already avoids).
|
||||
|
||||
#### 25.17.3 「乌尔比安3技能期间死亡会留在3技能位移后的位置复活,应回到初始部署位复活」 (item 28): the sources say where he fell — a question for the owner, no change
|
||||
|
||||
- **Checked**: knocked out during S3 he lies on the landing tile and comes back there — the rule of every operator moved
|
||||
off its board tile since 0.1.1 (§21.24, `Battle._layBody`): PRTS 卫戍协议/帮助 「原地留下一个“倒地干员”…自动部署至该位置」,
|
||||
whose one exception (「若干员被击倒的位置为其他干员或召唤物的初始位置,则…尝试返回其自身的初始位置」) does not apply to his
|
||||
landing tile. PRTS 乌尔比安 S3 备注 ④ (the 【返回】 at the skill's end) says nothing of a knock-out, and the client's S3
|
||||
templates (`ulpia_s3_*`: the 【移动】 respawn clips and flags) carry no other rule. With §25.17.2 he can no longer fall
|
||||
behind the red gate.
|
||||
- **Question for the owner**: keep "where he fell" (the sources) or send him back to his deployment tile (the report)?
|
||||
- Golden: unchanged.
|
||||
|
||||
#### 25.17.4 「退行的潮涌者的攻击无法触发菲莱2技能的受击反击(排查其他类似技能的干员)」 (item 30): the 「受到攻击时」 counters answer every damage instance from an enemy — `kits/shared/tier1.js byEnemyAttack`, `kits/ops/chess_char_3_06-philae.js` and the kits below
|
||||
|
||||
- **Seen**: the report's 退行的潮涌者 is the 巢涌者 (深溟 / 富营养的巢涌者 in this mode): no normal attack, its talent hurts
|
||||
every operator in range once a second — and 菲莱 S2 never answered it (measured: 0 blasts).
|
||||
- **Official** (ArknightsGameData buff_template_data): the pulse is an AdvancedApplyDamage with the enemy as its source
|
||||
(`enemy_dsubrl_aoe[aura]`); the counters fire on ON_TAKE_DAMAGE — `philae_s_2` with no filter at all, and on a source of
|
||||
the other side `inverse_damage` (星熊 S2, from its skill prefab), `inverse_damage[magic]` + `nian_s_2` (年 S2),
|
||||
`bubble_s_2` / `bubble_t_1` (泡泡 S2, 尖刺盾), `vendla_s_2` (刺玫 S2), `yu_s_1[inverse_damage]` (余 S1), `hsgma2_s_1` /
|
||||
`hsgma2_e_003_tr_take` (斩业星熊 S1, AST-X), `mlynar_t_2[inverse]` (玛恩纳 无动于衷). 棘刺 S2 (a 普通伤害 filter) and 信仰搅拌机
|
||||
S3 (any damage) were already right.
|
||||
- **Cause**: those kits required `dmg.isAttack`.
|
||||
- **Now**: `byEnemyAttack` = any damage instance from an enemy but a 流失 (PRTS 作战机制: 流失 triggers no 受击 events), an
|
||||
element 损伤, 无来源 damage or another counter / reflection (tags `counter` / `reflect`, no ping-pong); 菲莱 S2 takes any
|
||||
instance but a 流失 or a counter. `test/content/op_nian.test.js` pinned "a non-attack hit returns nothing" for 年 S2 —
|
||||
updated on purpose.
|
||||
- [ASSUMED]: a hit fully absorbed by a shield still counts (ON_TAKE_DAMAGE fires on the damage instance); a dodged one does not.
|
||||
- Found on the way, not changed: the pulse is `_ignoreForSp` officially (no 受击回复 SP, so it should not set off 雷蛇's
|
||||
talent either) and still gives SP here; `content/generic.js`'s parsed counter still takes attacks only (no unit uses it).
|
||||
- Golden: 19 scenarios where an enemy's non-attack damage reached one of these operators — roster-002 / 005 / 008 / 010 /
|
||||
012 / 016 / 033 / 044; bond-lateranoShip-low; fields boss-boss_2-solo, boss-boss_4-pair / -solo, hidden-boss_8-pair /
|
||||
-solo; matches solo-FUNNY-1 / -2, coop4-ABYSS-7, coop2-ABYSS-10-boosted; diy-051. Tests:
|
||||
`test/sim/feedback5-counters-any-damage.test.js`. Docs: docs/SIM.md (re-entrancy rule).
|
||||
|
||||
#### 25.17.5 「突袭盟约的干员如果带被动技能,复活之后不会立马突袭出去,还要等突袭CD」 (item 44): an in-place 复活 starts a deploy-timed skill again — `content/items/battle.js revivedInPlace`
|
||||
|
||||
- **Seen**: 缄默德克萨斯 (S3) revived by M3茧甲 or 埃芒加德 with nothing in range jumped 10.00 s later; after 不屈's real
|
||||
redeploy 0.23 s later. After a timed redeploy every passive member already jumped at once (measured for 宴, 缄默德克萨斯,
|
||||
斯卡蒂, 耀骑士临光, 伊内丝).
|
||||
- **Official**: PRTS 盟约记录 备注 — 「复活」 is 退场 + a 0-time / 0-cost redeploy, a new deployment, after which a deploy-timed
|
||||
skill runs again; a 突袭 member counts that running window as 技能就绪 (`raidPoll`, GitHub #49 / #109).
|
||||
- **Cause**: the remake revives in place (a `fatal` hook, §21.21): her window, over by then, stayed over and only the idle
|
||||
trigger was left.
|
||||
- **Now**: `revivedInPlace` also restarts an `activateOnDeploy` skill on the next tick — anew when its window had ended,
|
||||
back to its full duration when it still ran — so the member jumps at once; 砾 gets a fresh barrier, 缄默德克萨斯 a new
|
||||
sword rain. The SP reset and the other 部署时 effects of PRTS's form stay unmodelled (§21.21).
|
||||
- [ASSUMED]: none beyond §21.21's in-place form.
|
||||
- Golden: 1 scenario — roster-012 (the elite 缄默德克萨斯 revived in place three times). Tests:
|
||||
`test/sim/feedback5-raid-revive.test.js`. Docs: docs/SIM.md, DESIGN §5.4 (design/engine.md, the `fatal` hook).
|
||||
|
||||
#### 25.17.6 「干员银灰的普通攻击的音效错误的使用了3技能期间的攻击音效」 (item 54): an operator whose default mode is the unsuffixed ability never takes a skill mode's sound — `tools/assets/audio.mjs pickUnitSfx`, data/assets.json
|
||||
|
||||
- **Seen**: 银灰's normal attack swung with p_atk_silver_n and hit with p_imp_sword_n.
|
||||
- **Official** (audio_data, the local client's charpack): his normal attack is the Default mode's Combat — impact
|
||||
`ON_ABILITY_HIT.char_172_svrash.combat` p_imp_spear_n, no swing bank; `.attack.2` (silver swing, sword impact) is his S3
|
||||
mode, `.attack.1` his S2 mode.
|
||||
- **Cause**: the picker's skill-mode test is by file name (`_d` / `_h` / `_s`), and those files end in `_n`.
|
||||
- **Now**: an operator with a plain attack / combat bank (its default mode is the unsuffixed ability) never takes a
|
||||
numbered variant; those that number their default mode (`attack.0` …) keep the order. Of the 209 operators it changes
|
||||
4: 银灰, 雷蛇 (S2's lightning impact), 初雪 (her S1-2 mode's impact), 圣约送葬人 (S3_End's impact). data/assets.json was
|
||||
regenerated offline (`fetch-assets --offline --add-only --allow-shrink`; JSON compare: those 4 entries, the hash and
|
||||
stats). 银灰's official impact file was not on disk yet, so his entry stayed empty in the stream; at the merge one online
|
||||
`node tools/fetch-assets.mjs --add-only` downloaded p_imp_spear_n.mp3 (8.8 KB, the only new file) and the manifest lists
|
||||
his impact again (JSON compare with the stream's manifest: `char_172_svrash.hit`, the hash and stats).
|
||||
- Golden: unchanged. Tests: `test/feedback5-operator-sfx.test.js`. Docs: docs/ASSETS.md.
|
||||
|
||||
#### 25.17.7 Already answered or not a bug: 铃兰's trigger, 琳琅诗怀雅's champagne, the 突袭 玛恩纳, 归溟幽灵鲨 devoured, 荒芜拉普兰德 and 叙拉古 (items 2, 17, 16.1, 16.4, 46) — no change
|
||||
|
||||
- **Item 2** 「敌人在干员…铃兰技能范围内没有开技能,在攻击范围才开」: her default S3 狐火渺然 (「攻击范围扩大」, no class or charId
|
||||
row) was DEFAULT up to v0.1.4 — an enemy in her own 2-tile range; 0.2.0's ACTIVE_RANGE (§25.5, `resolveTrigger`) casts
|
||||
it with an enemy in its running range y-8 (3 tiles ahead), as for 忍冬 (§25.14.2). data/chess.json already says so.
|
||||
- **Item 17** 「琳琅诗怀雅的2技能的香槟只会在攻击范围内生成」: fixed by 0.2.0 WC (GitHub #116 item 2, §25.6): S2 “见面礼” throws
|
||||
on the placeable, walkable ground tiles of range x-6 — her tile and two tiles up / down / left / right (PRTS 备注
|
||||
「香槟炸弹放置范围:x-6」), onto an enemy's tile when one stands there. Pinned by `test/content/kits_t3.test.js`.
|
||||
- **Item 16.1** 「突袭转职玛恩纳触发突袭的频率低很多…攻击范围里有怪的时候即使长时间没攻击也不会突袭」: the bond text itself —
|
||||
「干员10秒内未进行攻击或技能就绪时,若范围内没有敌人」. A 解放者 never attacks with his skill off, so his 10 s are always met,
|
||||
and an enemy in his range (one he does not block keeps walking through it) is what holds the jump, as for every member.
|
||||
Should the owner have footage of the official game jumping with an enemy in range, that would be a new rule.
|
||||
- **Item 16.4** 「归鲨被吃的时候不是变替身而是进了再部署」: not reproduced — an 阿戈尔 devour mark switches her to her 替身 on
|
||||
normal, 联防 and boss fields; a sweep of 400 random chains (241 marked, 201 lethal) on this tree and on v0.1.2–v0.1.4:
|
||||
never a knock-out. A player who does not own her fields her 补位 stand-in Sharp (近卫-无畏者, no 替身).
|
||||
- **Item 46** 「荒芜拉普兰德开技能之后好像没有普攻了…叙拉古恐惧概率不高」: during her default S3 every drone is out chasing the
|
||||
enemies nearest to it (PRTS 技能流程), so she makes no attack of her own — the drones hit — and her attacks come back
|
||||
when it ends (measured). 叙拉古 6's true damage + fear is PRTS's rule: 0.139 % per 普通伤害 attempt, +0.139 % per miss,
|
||||
a counter shared by the player's members (3 % on average; measured 3.0 %).
|
||||
- Golden: unchanged. Pinned: `test/sim/feedback5-cb3-pins.test.js` (items 2, 16.1, 16.4, 46).
|
||||
|
||||
### 25.18 Community reports of 2026-10-06, stream CB4: enemies, bosses, waves, movement — `sim/battle/players.js onOwnBoard`, `content/bonds/addon/battle.js raidTile`, `content/enemies/archetypes.js kitPolluted`, `content/enemies/special.js kitRush`, `targeting.js canTargetAlly`
|
||||
|
||||
The owner's second collection of community reports (2026-10-06/07) was split over five streams; CB4 took the items about
|
||||
|
||||
+6
-1
@@ -286,9 +286,14 @@ export function resolveHit(b, u, prof, target, info, x, y) {
|
||||
let mulT = skillMul;
|
||||
if (prof.dmgMul) { const m = typeof prof.dmgMul === 'function' ? prof.dmgMul(b, u, target) : prof.dmgMul; if (Number.isFinite(m)) mulT *= m; }
|
||||
const hits = prof.hitsFn ? prof.hitsFn(b, u, info) : Math.max(1, prof.hits || 1);
|
||||
// `hitDmgMul` (professions.js header): each instance's 伤害倍率 — the DamageInfo `mul`, after DEF / RES — and only the
|
||||
// first instance may give 受击回复 (砾's two 50 % hits, PRTS 砾 特性备注)
|
||||
const split = Number.isFinite(prof.hitDmgMul) && prof.hitDmgMul > 0 ? prof.hitDmgMul : null;
|
||||
let dealtMain = 0;
|
||||
for (let h = 0; h < hits && target.alive; h++) {
|
||||
dealtMain += b.dealDamage(u, target, { amount: atk * scale * mulT, type: baseType, isAttack: true, isSkill: info.isSkill, tags: prof.tags || [], attackId });
|
||||
const d = { amount: atk * scale * mulT, type: baseType, isAttack: true, isSkill: info.isSkill, tags: prof.tags || [], attackId };
|
||||
if (split != null) { d.mul = split; if (h > 0) d.noSp = true; }
|
||||
dealtMain += b.dealDamage(u, target, d);
|
||||
}
|
||||
dealtTotal += dealtMain;
|
||||
if (prof.onHitStatus && target.alive) b.applyStatus(target, prof.onHitStatus.key, { duration: prof.onHitStatus.duration, source: u, value: prof.onHitStatus.value });
|
||||
|
||||
@@ -79,7 +79,8 @@ export class BattlePlayers {
|
||||
* tiles its pieces are deployed on) mapped onto this field — the 联防 right-hand helper's +8 columns, the boss field's
|
||||
* rows 2–5, the mirrored right half of a pair (whatever coordinates the player's input uses). Never the hand / 临时
|
||||
* 整备区 rows of a boss field (rows 0–1, inside BOSS_RECT) nor the other half of a 联防 or boss field. Automatic
|
||||
* redeployments that must stay where the player could deploy read it (the 突袭 landing, bonds/addon/battle.js raidTile).
|
||||
* redeployments and moves that must stay where the player could deploy read it (the 突袭 landing, bonds/addon/battle.js
|
||||
* raidTile; 乌尔比安's S3 【移动】, kits/ops/chess_char_5_05-ulpia.js).
|
||||
*/
|
||||
onOwnBoard(ps, r, c) {
|
||||
if (!ps) return false;
|
||||
|
||||
@@ -246,8 +246,26 @@ function hammerState(battle, rt, u) {
|
||||
*/
|
||||
export function deploymentOf(u) { return `${u.deploySeq}:${u.mem.revives | 0}`; }
|
||||
|
||||
/** An in-place 复活 (M3茧甲, 埃芒加德) happened: a new deployment for the once-per-deployment lock (deploymentOf). */
|
||||
export function revivedInPlace(u) { if (u && u.mem) u.mem.revives = (u.mem.revives | 0) + 1; }
|
||||
/**
|
||||
* An in-place 复活 (M3茧甲, 埃芒加德) happened. PRTS's 复活 is 退场 + a 0-time / 0-cost redeploy (PRTS 盟约记录 备注) — a new
|
||||
* deployment, of which the remake carries: the once-per-deployment lock (deploymentOf) and a deploy-timed skill ("部署后…秒内",
|
||||
* SkillSpec `activateOnDeploy`: 缄默德克萨斯 S1–S3, 宴 S2, 斯卡蒂 S2, 砾's barrier …) running again — started anew when its window
|
||||
* had ended, its window back to the full duration when it still ran (the next tick, out of the damage pipeline that set the
|
||||
* revive off). Community report of 2026-10-06 (item 44): a 突袭 member counts such a running window as 技能就绪
|
||||
* (bonds/addon/battle.js raidPoll), and after an in-place revive it waited out the 10 s idle time instead of jumping at once
|
||||
* as after a redeploy. The SP reset and the other 部署时 effects of PRTS's form stay unmodelled (DESIGN §21.21).
|
||||
*/
|
||||
export function revivedInPlace(u) {
|
||||
if (!u || !u.mem) return;
|
||||
u.mem.revives = (u.mem.revives | 0) + 1;
|
||||
const sk = u.skill;
|
||||
if (!sk || sk.noSkill || !sk.spec || !sk.spec.activateOnDeploy || !sk.battle) return;
|
||||
const seq = u.deploySeq, n = u.mem.revives;
|
||||
sk.battle.after(0, () => {
|
||||
if (!u.alive || !u.deployed || u.deploySeq !== seq || u.mem.revives !== n || u.skill !== sk) return;
|
||||
if (sk.active) { if (sk.duration > 0) sk.timeLeft = sk.duration; } else sk.activate('deploy', { free: true });
|
||||
}, { owner: u });
|
||||
}
|
||||
|
||||
/**
|
||||
* Does `u` hold 坚固维式重锤's 不死 right now — a window started in this deployment that has not run out? The window lives
|
||||
|
||||
@@ -6,8 +6,9 @@ import { onDefaultSkill } from '../shared/tier2.js';
|
||||
|
||||
export default {
|
||||
// ---------------------------------------------------------------------------------------------------------------
|
||||
// 2_08 泡泡 “挨打”: stops attacking; DEF +def, taunt +taunt_level, each attack received returns atk_scale × DEF phys
|
||||
// damage to the attacker. 尖刺盾: attackers get ATK −atk for `duration` s. Elite module (PRO-X): DEF +def while blocking.
|
||||
// 2_08 泡泡 “挨打”: stops attacking; DEF +def, taunt +taunt_level, each enemy damage instance received (its attack or not:
|
||||
// the official bubble_s_2 / bubble_t_1 fire on ON_TAKE_DAMAGE — tier1 byEnemyAttack) returns atk_scale × DEF phys damage
|
||||
// to its source. 尖刺盾: that source gets ATK −atk for `duration` s. Elite module (PRO-X): DEF +def while blocking.
|
||||
// S1 防御力强化·β型 (alt, TAKE_DAMAGE from data): DEF +def for its duration; the counter belongs to “挨打” only.
|
||||
chess_char_2_08_a: (bb, chess) => {
|
||||
const t = talentBb(chess, 0);
|
||||
|
||||
@@ -3,6 +3,15 @@
|
||||
|
||||
import { num, talentBb, installAura } from '../shared/tier1.js';
|
||||
|
||||
/**
|
||||
* 砾's normal attack (PRTS 砾 特性备注): "在砾的攻击动作下,每次普通攻击造成两段伤害,但是每段最终只会造成50%的伤害(在计算防御/减伤后,在
|
||||
* 重设伤害前);第二段伤害不会触发目标的受击回复" — two damage instances of 50 % 伤害倍率 each (DamageInfo `mul`, after DEF: not a 50 %
|
||||
* 攻击倍率), so a 频次 enemy loses 2 per attack; the second carries no 受击回复 (ai.js resolveHit `hitDmgMul`). Every attack she
|
||||
* makes is a normal attack (both her skills are passive).
|
||||
*/
|
||||
const GRAVEL_HITS = 2;
|
||||
const GRAVEL_HIT_DMG_MUL = 0.5;
|
||||
|
||||
export default {
|
||||
// ---------------------------------------------------------------------------------------------------------------
|
||||
// 2_12 砾 鼠群 (passive): at each deployment a barrier of hp_ratio × max HP that decays to 0 over `duration` s
|
||||
@@ -10,10 +19,11 @@ export default {
|
||||
// 快速部署: own deployment cost +cost (−1). Elite 小个子支援: every unit whose initial deployment cost ≤ cond.cost
|
||||
// DEF +def while 砾 is on the field. (Elite module withdraw refund: no manual retreat in battle ⇒ no effect.)
|
||||
// S1 影袭 (alt, passive): at each deployment DEF +def, decaying linearly to 0 over `duration` s, updated once per
|
||||
// second (PRTS: "防御力加成每秒更新一次").
|
||||
// second (PRTS: "防御力加成每秒更新一次"). Trait note: every normal attack hits twice at 50 % (GRAVEL_HIT_DMG_MUL above).
|
||||
chess_char_2_12_a: (bb, chess) => {
|
||||
const t = talentBb(chess, 0);
|
||||
return {
|
||||
trait: { hits: GRAVEL_HITS, hitDmgMul: GRAVEL_HIT_DMG_MUL },
|
||||
skill: {
|
||||
kind: 'duration', activateOnDeploy: true, duration: num(bb.duration, 10), spCost: 0, spType: 'none', trigger: 'NEVER',
|
||||
onStart({ battle, unit }) {
|
||||
|
||||
@@ -2,10 +2,12 @@
|
||||
// Conventions of the tier-3 kits: ../shared/tier3.js; kit contract and rules: ../README.md.
|
||||
|
||||
import { num, defOf, talentBb, traitBb, selectedId, altSkills, fx, NINE, giveSp } from '../shared/tier3.js';
|
||||
import { isHpLoss } from '../../../damage.js';
|
||||
|
||||
export default {
|
||||
// ---- 3_06 菲莱 · 本源铁卫 — S2 冥河诅咒: stops attacking, HP +; when attacked blasts the ground enemies of the 3×3
|
||||
// around her (PRTS 备注: range x-4; arts + ep_damage_ratio × ATK apoptosis, aoe_cd); ATK + once hit by element
|
||||
// ---- 3_06 菲莱 · 本源铁卫 — S2 冥河诅咒: stops attacking, HP +; "受到攻击时" — any damage instance she takes (official
|
||||
// philae_s_2: ON_TAKE_DAMAGE with no source or attack filter) — blasts the ground enemies of the 3×3 around her
|
||||
// (PRTS 备注: range x-4; arts + ep_damage_ratio × ATK apoptosis, aoe_cd); ATK + once hit by element
|
||||
// damage; 神河谕使: 元素损伤 taken −damage_resistance, +SP on apoptosis
|
||||
// 精锐 module PRP-X "阻挡敌人时,自身造成的元素损伤提升15%": EVERY element fill she deals (the S2 blast, a 灼燃维式重锤
|
||||
// she carries …) ×ep_damage_scale while she blocks — an `elementHit` multiplier, like 余's
|
||||
@@ -85,7 +87,11 @@ export default {
|
||||
if (isS2 && sk && sk.active && !unit.findBuff('skill:philae_rage')) battle.addBuff(unit, { key: 'skill:philae_rage', mods: { atkPct: num(bb.atk) }, visible: true });
|
||||
return;
|
||||
}
|
||||
if (!isS2 || !sk || !sk.active || !ctx.dmg?.isAttack || !ctx.source || ctx.source.side !== 'enemy') return;
|
||||
// the official philae_s_2 (buff_template_data) fires on ON_TAKE_DAMAGE with no filter: any damage instance — an
|
||||
// enemy's attack, a skill hit, 深溟巢涌者's pulse, a 无来源 hit — never a 流失 or an element 损伤 (above), nor a
|
||||
// counter / reflection. Until 0.2.0 enemy attacks only (community report of 2026-10-06, item 30)
|
||||
const d = ctx.dmg;
|
||||
if (!isS2 || !sk || !sk.active || !d || isHpLoss(d) || (d.tags || []).some((t) => t === 'counter' || t === 'reflect')) return;
|
||||
if (battle.time < (unit.mem.philaeCd ?? -Infinity)) return;
|
||||
unit.mem.philaeCd = battle.time + cd;
|
||||
// "周围的地面敌人" = range x-4, the 3×3 tiles around her (PRTS 备注)
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
// Conventions of the tier-4 kits: ../shared/tier4.js; kit contract and rules: ../README.md.
|
||||
|
||||
import { AURA, num, tbb, whileDeployed, pulse, toggleBuff, isSel, alt, withDefaults } from '../shared/tier4.js';
|
||||
import { byEnemyAttack } from '../shared/tier1.js';
|
||||
|
||||
export default withDefaults({
|
||||
// ===== 星熊 (protector) S2 荆棘 (passive) — DEF +13 %, counters every attacker for 65 % ATK phys; talents
|
||||
// ===== 星熊 (protector) S2 荆棘 (passive) — DEF +13 %, answers every enemy damage instance with 65 % ATK phys on its source; talents
|
||||
// S1 战意 (TAKE_DAMAGE: DEF/ATK up); S3 力之锯 (ATK/DEF up, cuts every enemy on her front tile — all enemies of her
|
||||
// range); module PRO-X (护身符): DEF +20 % while blocking
|
||||
chess_char_4_17_a: (bb, chess, def) => {
|
||||
@@ -40,7 +41,8 @@ export default withDefaults({
|
||||
if (!S2) return;
|
||||
battle.on('damaged', (c) => {
|
||||
const src = c.source;
|
||||
if (c.target !== unit || !unit.alive || !src || src.side !== 'enemy' || !src.alive || !c.dmg?.isAttack) return;
|
||||
// 荆棘 = the official inverse_damage: every enemy damage instance, not its attacks only (tier1 byEnemyAttack)
|
||||
if (c.target !== unit || !unit.alive || !byEnemyAttack(c) || !src.alive) return;
|
||||
battle.dealDamage(unit, src, { amount: unit.s.atk * num(bb.atk_scale, 0.65), type: 'phys', canDodge: false, isSkill: true, tags: ['counter'] });
|
||||
battle.fx('thorns', { x: unit.x, y: unit.y, id: unit.id });
|
||||
}, { owner: unit });
|
||||
|
||||
@@ -13,7 +13,8 @@ export default {
|
||||
// ---------------------------------------------------------------------------------------------------------------
|
||||
// 乌尔比安 — S3 必须开辟的通路 (25 s, CUSTOM_RANGE row ahead): max HP/ATK +, throws an anchor forward that stops on the
|
||||
// first enemy or at max distance — on his own tile while he blocks: 135 % ATK phys + 6 s stun around it
|
||||
// (projectile_range); moves onto the anchor tile when deployable and not his own (a 从不混淆的方向 marker keeps his tile)
|
||||
// (projectile_range); moves onto the anchor tile when deployable (a tile of his own board) and not his own (a 从不混淆的方向
|
||||
// marker keeps his tile)
|
||||
// and returns at skill end — both 【移动】, i.e. free redeploys (Battle.moveRedeploy; the return empties his SP).
|
||||
// T1 本性的坚守: heal 100 (160 below 50 %) on every hit taken. T2 血脉的哺养: per kill +120 max HP / +30 ATK (×9),
|
||||
// other Abyssal Hunters +50 %. Module (elite): healing received ×1.2.
|
||||
@@ -90,8 +91,12 @@ export default {
|
||||
// anchor on his own tile leaves him where he stands, no marker, nothing to return from [ASSUMED: the "tile one
|
||||
// beyond the landing" is not tried when the landing is his own tile]
|
||||
if (stop === 0 || !unit.alive) return;
|
||||
// PRTS 备注: landing tile > the tile one beyond it > his own tile (a deployable, free, unreserved melee tile)
|
||||
const ok = ([r, c]) => (r !== unit.tileR || c !== unit.tileC) && battle.grid.inRect(r, c) && battle.grid.canStand(r, c) && !battle.grid.isObstacle(r, c) && !battle.isReservedTile(r, c);
|
||||
// PRTS 备注: landing tile > the tile one beyond it > his own tile (a deployable, free, unreserved melee tile).
|
||||
// "可部署" is a tile his player may deploy on: his own board (Battle.onOwnBoard) — never the other half of a 联防 or
|
||||
// boss field nor a boss field's hand / 临时整备区 rows. Community report of 2026-10-06 (item 27) 「乌尔比安使用3技能会在
|
||||
// 联防阶段跳到红门后」: on the one-helper 联防 map (escaped_single, enemies from the middle gate at col 10) an anchor that
|
||||
// met no enemy flew on to the right half, where no enemy ever walks, and he moved there for the whole skill
|
||||
const ok = ([r, c]) => (r !== unit.tileR || c !== unit.tileC) && battle.grid.inRect(r, c) && battle.onOwnBoard(unit.player, r, c) && battle.grid.canStand(r, c) && !battle.grid.isObstacle(r, c) && !battle.isReservedTile(r, c);
|
||||
const dest = [[sr, sc], frontOf(unit.tileR, unit.tileC, unit.dir, stop + 1)].find(ok);
|
||||
if (dest == null) return;
|
||||
const home = [unit.tileR, unit.tileC];
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
num, on, inRange, talent, skillGrid, batPct, mods, inFaction, isOp, selectedId, lazySkills, skillRange, leaderOf,
|
||||
whileOn, permBuff,
|
||||
} from '../shared/tier5.js';
|
||||
import { byEnemyAttack } from '../shared/tier1.js';
|
||||
|
||||
/** 玛恩纳 游侠 "周围存在3名及以上敌人" radius (8-neighbourhood). */
|
||||
const AROUND_RADIUS = 1.5;
|
||||
@@ -18,7 +19,7 @@ export default {
|
||||
// PRTS 备注 the trait bonus drops by 10 % (per_kill_reduce, absolute: +400 % → +390 %) for each enemy knocked out by
|
||||
// his own attack (or the damage it carries — not 无动于衷's reflection, not a mark another operator's attack set off),
|
||||
// settled after that attack, never below +0 %. T1 游侠: ×1.1 ATK on attacks (×1.15 and −15 % damage taken with ≥3
|
||||
// enemies around). T2 无动于衷: taunt +1, Kazimierz ops reflect 15 % of his ATK as true damage when attacked.
|
||||
// enemies around). T2 无动于衷: taunt +1, Kazimierz ops reflect 15 % of his ATK as true damage when an enemy damages them.
|
||||
// S1 未声张的怒火 (duration, SEARCH): attacks attack@atk_scale × ATK, DEF +. S2 未宽解的悲哀 (duration): skill range,
|
||||
// BAT +0.3 s, attacks attack@atk_scale × ATK twice; a kill of his own attacks during the skill keeps the trait ramp
|
||||
// when it ends. S1 / S2 have no 对空 note: ground only, like his trait. S2's data rule is ACTIVE_RANGE on its 2-3 (the
|
||||
@@ -85,7 +86,9 @@ export default {
|
||||
if (!(scale > 0)) return;
|
||||
battle.on('damaged', (c) => {
|
||||
const a = c.target, src = c.source;
|
||||
if (a.side !== 'ally' || !isOp(a) || !isKazimierz(a) || !src || src.side !== 'enemy' || !src.alive || !c.dmg?.isAttack) return;
|
||||
// the official mlynar_t_2[inverse] (ON_TAKE_DAMAGE, InverseDamage from an enemy source): every enemy damage instance
|
||||
// a Kazimierz operator takes, not its attacks only (tier1 byEnemyAttack)
|
||||
if (a.side !== 'ally' || !isOp(a) || !isKazimierz(a) || !byEnemyAttack(c) || !src.alive) return;
|
||||
if (!on(unit) || leaderOf(battle, unit) !== unit) return;
|
||||
battle.dealDamage(unit, src, { amount: unit.s.atk * scale, type: 'true', canDodge: false, tags: ['talent', 'reflect'] });
|
||||
}, { owner: unit });
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
num, bv, tbb, moduleBb, live, opsOf, ANY, onDefaultSkill, selectedSkill, skillGridOf, AROUND8, onElementHit,
|
||||
elementDmg, aura,
|
||||
} from '../shared/tier6.js';
|
||||
import { holdProtect } from '../shared/tier1.js';
|
||||
import { holdProtect, byEnemyAttack } from '../shared/tier1.js';
|
||||
|
||||
/**
|
||||
* "传送至自身位置": a ground enemy that can reach `unit`'s tile on the ground grid is moved onto it (unblocked, its
|
||||
@@ -40,8 +40,8 @@ function yu(bb, chess, def) {
|
||||
// "将第二天赋效果赋予全场所有干员" belongs to S3 (the default skill) only
|
||||
const s3On = (unit) => isDef && !!unit.skill?.active;
|
||||
const skills = {
|
||||
// S1 今日做东 (TAKE_DAMAGE, hurt SP): passive taunt +taunt_level; active: HP / DEF +, every attack taken ⇒
|
||||
// ep_damage_ratio × ATK 灼燃损伤 on the attacker (install below)
|
||||
// S1 今日做东 (TAKE_DAMAGE, hurt SP): passive taunt +taunt_level; active: HP / DEF +, every enemy damage instance taken ⇒
|
||||
// ep_damage_ratio × ATK 灼燃损伤 on its source (install below)
|
||||
skchr_yu_1: { kind: 'duration', mods: { hpPct: num(bb.max_hp), defPct: num(bb.def) } },
|
||||
// S2 厚礼上宾 (cast with an enemy on its x-1: the data's SKILL_RANGE, a deliberate deviation from the 重装 TAKE_DAMAGE
|
||||
// row — tools/build-data.mjs TRIGGER_DEVIATIONS, DESIGN §22.10): atk_scale × ATK arts on every enemy of the skill range
|
||||
@@ -71,7 +71,8 @@ function yu(bb, chess, def) {
|
||||
battle.addBuff(unit, { key: 'yu:host', mods: { taunt: num(bb.taunt_level, 1) }, persist: true, allowDead: true });
|
||||
battle.on('damaged', (ctx) => {
|
||||
const s = ctx.source;
|
||||
if (ctx.target !== unit || !unit.skill?.active || !s || s.side !== 'enemy' || !s.alive || !ctx.dmg?.isAttack) return;
|
||||
// "每次受到攻击" = the official yu_s_1[inverse_damage]: every enemy damage instance (tier1 byEnemyAttack)
|
||||
if (ctx.target !== unit || !unit.skill?.active || !byEnemyAttack(ctx) || !s.alive) return;
|
||||
elementDmg(battle, unit, s, 'burn', unit.s.atk * num(bb.ep_damage_ratio), ['skill']);
|
||||
}, { owner: unit });
|
||||
},
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
// data's 'phys' too since 0.2.0 WE2 — build-data classifyAttack) and arts while one runs (every skill's attack override); block 3, ground-only
|
||||
// melee on her 1-1. Module AST-X 无迹 adds "且攻击和受到攻击时对目标额外造成10%攻击力的法术伤害" (trait bb atk_scale): every
|
||||
// damage instance of her normal attacks (skill attacks included; not the shield, a counter or the module's own damage)
|
||||
// is followed by atk_scale × ATK arts on that enemy (附加伤害: no dodge), and every enemy attack she takes returns
|
||||
// atk_scale × ATK arts (普通伤害) to the attacker — whether a skill runs or not [ASSUMED: PRTS's list of the checked
|
||||
// is followed by atk_scale × ATK arts on that enemy (附加伤害: no dodge), and every enemy damage instance she takes
|
||||
// returns atk_scale × ATK arts (普通伤害) to its source (tier1 byEnemyAttack) — whether a skill runs or not [ASSUMED: PRTS's list of the checked
|
||||
// conditions names no skill period].
|
||||
// - T1 业火 "生命降至0时进入“我执”…": a lethal damage instance leaves her on the field in 我执 instead (the damage past her
|
||||
// HP opens the negative pool — the engine keeps her at its 1-HP floor for the official 0); in 我执 every later damage
|
||||
@@ -34,8 +34,8 @@
|
||||
// - T2 鬼之架势 "在场时,自身获得最高+50法术抗性和35%攻击力的坚忍(损失70%生命值时达到最大加成)": RES +min_magic_resistance and ATK
|
||||
// +min_atk scaled linearly by the HP lost from max_hp_ratio down to min_hp_ratio (坚忍), re-read every tick; in 我执 at
|
||||
// its maximum. AST-X stage 3: the maximum at 50 % lost (min_hp_ratio 0.5) and "达到最大加成时,攻击力额外+15%" (atk).
|
||||
// - S1 恶业苦果 (AUTO, 受击回复 SP, 持续时间无限 — a toggle): ATK +atk, DEF +def, arts attacks; every enemy attack she takes
|
||||
// deals atk_scale × ATK arts to the attacker (a direct pick of the damage source, enemies only). A self buff: the owner's
|
||||
// - S1 恶业苦果 (AUTO, 受击回复 SP, 持续时间无限 — a toggle): ATK +atk, DEF +def, arts attacks; every enemy damage instance
|
||||
// she takes deals atk_scale × ATK arts to its source (a direct pick of the damage source, enemies only). A self buff: the owner's
|
||||
// AUTO rule fires it as soon as its SP is full (`trigger: 'SP_FULL'`, as 引星棘刺 S1 — kits/README.md checklist 5).
|
||||
// - S2 无始无明 (AUTO, attack SP; data DEFAULT): the cast replaces the attack about to be made — the shield throw, three hits
|
||||
// of attack@atk_scale × ATK arts on every enemy she blocks (none blocked: her target [ASSUMED]); then the shield circles
|
||||
@@ -52,7 +52,7 @@
|
||||
// refund of a withdrawal is not modelled — no retreat in the sim refunds DP). No strategy of this mode closes it: PRTS
|
||||
// 帮助 lists the 上半 row that did as removed in 下半, so in a fight the skill simply runs its `duration`.
|
||||
|
||||
import { num, talentBb, traitBb, skillRec, up } from '../shared/tier1.js';
|
||||
import { num, talentBb, traitBb, skillRec, up, byEnemyAttack } from '../shared/tier1.js';
|
||||
import { canTargetEnemy } from '../../../targeting.js';
|
||||
import { bodyInRadius } from '../../../body.js';
|
||||
import { hasHp } from '../../../damage.js';
|
||||
@@ -252,15 +252,17 @@ export default {
|
||||
} },
|
||||
],
|
||||
install(battle, unit) {
|
||||
// S1 恶业苦果: every enemy attack she takes ⇒ atk_scale × ATK arts back to the attacker
|
||||
// S1 恶业苦果: every enemy damage instance she takes (the official hsgma2_s_1 on ON_TAKE_DAMAGE, not its attacks only:
|
||||
// tier1 byEnemyAttack) ⇒ atk_scale × ATK arts back to its source
|
||||
battle.on('damaged', (c) => {
|
||||
const s = c.source;
|
||||
if (c.target !== unit || !unit.alive || unit.skill?.id !== S1 || !unit.skill.active) return;
|
||||
if (!s || s.side !== 'enemy' || !s.alive || !c.dmg?.isAttack) return;
|
||||
if (!byEnemyAttack(c) || !s.alive) return;
|
||||
battle.dealDamage(unit, s, { amount: unit.s.atk * num(b1.atk_scale), type: 'arts', canDodge: false, isSkill: true, ignoreSelect: true, tags: ['skill', 'counter'] });
|
||||
battle.fx('counter', { x: s.x, y: s.y, id: unit.id });
|
||||
}, { owner: unit });
|
||||
// AST-X 无迹: her attack damage ⇒ +atk_scale × ATK arts (附加伤害); an enemy attack she takes ⇒ atk_scale × ATK arts back
|
||||
// AST-X 无迹: her attack damage ⇒ +atk_scale × ATK arts (附加伤害); an enemy damage instance she takes (the official
|
||||
// hsgma2_e_003_tr_take: ON_TAKE_DAMAGE from the other side) ⇒ atk_scale × ATK arts back
|
||||
const astx = num(tb.atk_scale);
|
||||
if (astx > 0) {
|
||||
battle.on('damaged', (c) => {
|
||||
@@ -270,7 +272,7 @@ export default {
|
||||
}, { owner: unit, priority: -20 });
|
||||
battle.on('damaged', (c) => {
|
||||
const s = c.source;
|
||||
if (c.target !== unit || !unit.alive || !s || s.side !== 'enemy' || !s.alive || !c.dmg?.isAttack) return;
|
||||
if (c.target !== unit || !unit.alive || !byEnemyAttack(c) || !s.alive) return;
|
||||
battle.dealDamage(unit, s, { amount: unit.s.atk * astx, type: 'arts', ignoreSelect: true, tags: ['module', ASTX, 'counter'] });
|
||||
}, { owner: unit });
|
||||
}
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
// no-SP-during-a-skill rule, tier1 giveSp).
|
||||
// - S1 锡灼 (MANUAL, time SP; data DEFAULT — the owner's 重装 cast-in-range exception, rawRule TAKE_DAMAGE): `duration` s of
|
||||
// DEF +def and ATK +atk; normal attacks deal arts damage.
|
||||
// - S2 铜印 (MANUAL; data DEFAULT): `duration` s — stops attacking; DEF +def, block +block_cnt; every enemy attack she takes
|
||||
// (each damage instance of one, as 星熊 荆棘 / 泡泡) deals atk_scale × ATK arts to the attacker and silences it `silence`
|
||||
// - S2 铜印 (MANUAL; data DEFAULT): `duration` s — stops attacking; DEF +def, block +block_cnt; every enemy damage instance she
|
||||
// takes (its attack or not, as 星熊 荆棘 / 泡泡) deals atk_scale × ATK arts to its source and silences it `silence`
|
||||
// s ("失去特殊能力"): a direct pick of the damage source (ignoreSelect), enemies only (PRTS 备注), even when a 护盾 layer
|
||||
// negated the hit.
|
||||
// - S3 铁御 (MANUAL; data DEFAULT — its x-2 is a 技能范围 for the allies, no attack-range change): `duration` s of ATK
|
||||
@@ -37,7 +37,7 @@
|
||||
// −one_minus_status_resistance), refreshed every AURA s while the skill runs; two 年 of a shared field keep the stronger
|
||||
// (installAura's rule). The DEF / block buff ends with the skill, the 抵抗 within AURA_DUR.
|
||||
|
||||
import { num, talentBb, traitBb, skillRec, statBuff, toggleBuff, up, giveSp } from '../shared/tier1.js';
|
||||
import { num, talentBb, traitBb, skillRec, statBuff, toggleBuff, up, giveSp, byEnemyAttack } from '../shared/tier1.js';
|
||||
import { absoluteRangeKeys } from '../../../targeting.js';
|
||||
import { COLS } from '../../../constants.js';
|
||||
|
||||
@@ -154,12 +154,13 @@ export default {
|
||||
battle.addBuff(unit, { key: FORT, mods: nz({ hpPct: perHp * n, healingTakenMul: Math.min(healMax, healBase + healAdd * n) }), data: { n }, tags: ['trait'] });
|
||||
}, { owner: unit });
|
||||
}
|
||||
// S2 铜印: every enemy attack she takes ⇒ atk_scale × ATK arts back to the attacker + silence `silence` s
|
||||
// S2 铜印: every enemy damage instance she takes (the official inverse_damage[magic] + nian_s_2 on ON_TAKE_DAMAGE, not
|
||||
// its attacks only: tier1 byEnemyAttack) ⇒ atk_scale × ATK arts back to its source + silence `silence` s
|
||||
const scale = num(b2.atk_scale), sil = num(b2.silence);
|
||||
battle.on('damaged', (c) => {
|
||||
const src = c.source;
|
||||
if (c.target !== unit || !unit.alive || unit.skill?.id !== S2 || !unit.skill.active) return;
|
||||
if (!src || src.side !== 'enemy' || !src.alive || !c.dmg?.isAttack) return;
|
||||
if (!byEnemyAttack(c) || !src.alive) return;
|
||||
if (scale > 0) battle.dealDamage(unit, src, { amount: unit.s.atk * scale, type: 'arts', canDodge: false, isSkill: true, ignoreSelect: true, tags: ['skill', 'counter'] });
|
||||
if (sil > 0 && src.alive) battle.applyStatus(src, 'silence', { duration: sil, source: unit });
|
||||
battle.fx('counter', { x: src.x, y: src.y, id: unit.id });
|
||||
|
||||
@@ -31,6 +31,7 @@ import { COLS, TICK } from '../../../constants.js';
|
||||
import { absoluteRangeKeys, sortEnemyTargets } from '../../../targeting.js';
|
||||
import { offsetTile } from '../../../dir.js';
|
||||
import { bodyInKeys, bodyTileReach } from '../../../body.js';
|
||||
import { isHpLoss } from '../../../damage.js';
|
||||
|
||||
// =================================================================================================================
|
||||
// shared helpers (named exports; content/index.js only merges the default export)
|
||||
@@ -66,8 +67,21 @@ export const cheb = (a, b) => (b.hitArea ? bodyTileReach(b, Math.round(a.y), Mat
|
||||
: Math.max(Math.abs(Math.round(a.y) - Math.round(b.y)), Math.abs(Math.round(a.x) - Math.round(b.x))));
|
||||
/** Normal attack hit on its primary target (no splash, no chain jump). */
|
||||
export const isMainHit = (dmg) => !!dmg && dmg.isAttack && !dmg.isSplash && !(dmg.tags && dmg.tags.includes('chain'));
|
||||
/** Damage ctx caused by an enemy's attack. */
|
||||
export const byEnemyAttack = (ctx) => !!ctx.source && ctx.source.side === 'enemy' && !!ctx.dmg && ctx.dmg.isAttack;
|
||||
/**
|
||||
* `damaged` ctx that sets off a "受到攻击时" counter: a damage instance from an enemy, of any kind — its normal attack, a
|
||||
* skill hit, an area pulse (深溟巢涌者's 无途径 法术伤害). The official counters fire on ON_TAKE_DAMAGE from a source of the
|
||||
* other side, not on attacks only (ArknightsGameData buff_template_data: inverse_damage / inverse_damage[magic] — 星熊 S2,
|
||||
* 年 S2 —, bubble_s_2 / bubble_t_1 — 泡泡 —, vendla_s_2 — 刺玫 —, yu_s_1[inverse_damage] — 余 S1 —, hsgma2_s_1 /
|
||||
* hsgma2_e_003_tr_take — 斩业星熊 —, mlynar_t_2[inverse] — 玛恩纳 无动于衷; 菲莱 S2's philae_s_2 checks no source at all).
|
||||
* Never a 流失 (PRTS 作战机制 "生命流失…不会触发反伤、受击回复等受到攻击触发的时点"), an element 损伤 (its own event), 无来源 damage
|
||||
* (no source to strike back) or another counter / reflection (tags 'counter' / 'reflect': no ping-pong). Community report
|
||||
* of 2026-10-06 (item 30): it took enemy attacks only, so 深溟巢涌者's pulse never set a counter off.
|
||||
*/
|
||||
export const byEnemyAttack = (ctx) => {
|
||||
const s = ctx.source, d = ctx.dmg;
|
||||
if (!s || s.side !== 'enemy' || !d || d.sourceless || ctx.type === 'element' || isHpLoss(d)) return false;
|
||||
return !(Array.isArray(d.tags) && (d.tags.includes('counter') || d.tags.includes('reflect')));
|
||||
};
|
||||
/**
|
||||
* `damaged` ctx of a damage that removed HP and can give 受击回复 SP — the engine's rule (damage.js applyHpLoss: not a 流失
|
||||
* (`noSp`, Battle.loseHp), not an element 损伤), whatever its source: an attack, a zone, the 无来源 源石溶剂 tick.
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
// healThrough(healer, ally) → bool (a healer that selects and heals that ally through its 禁疗 — Battle
|
||||
// injuredAlliesInKeys, damage.js heal; 凯尔希 on her Mon3tr)
|
||||
// hitsFn(battle, unit, info) → n (info: the hit's { isSkill, index, attackId, energy })
|
||||
// hitDmgMul n (伤害倍率 of each of the `hits` instances on the main target: DamageInfo `mul`, applied after DEF / RES
|
||||
// and the damage multipliers, not 攻击倍率 — a 频次 enemy still loses 1 per instance; the instances after
|
||||
// the first carry `noSp`, no 受击回复: 砾's two 50 % hits, PRTS 砾 特性备注 — ai.js resolveHit)
|
||||
// install(battle, unit) — per-unit hooks, called once at setup
|
||||
// storeEnergy(battle, unit) → bool / releaseEnergy(battle, unit) → n (秘术师: the attack check found no valid target ⇒
|
||||
// store one energy, false when full; the energies leaving with an attack — installMystic)
|
||||
|
||||
@@ -127,7 +127,7 @@ test('S1 锡灼 (23 / 26 s): DEF +40 % / +55 %, ATK +20 % / +30 %, her normal at
|
||||
}
|
||||
});
|
||||
|
||||
test('S2 铜印 (31 / 32 s): stops attacking; DEF +80 % / +100 %, block +1; every enemy attack she takes returns 60 % / 70 % ATK arts to the attacker (ranged ones too, a direct pick) and silences it 3 s; nothing for a non-attack hit, nothing once it ends', () => {
|
||||
test('S2 铜印 (31 / 32 s): stops attacking; DEF +80 % / +100 %, block +1; every enemy damage instance she takes (its attack or not — official ON_TAKE_DAMAGE) returns 60 % / 70 % ATK arts to its source (ranged ones too, a direct pick) and silences it 3 s; nothing for a 流失, nothing once it ends', () => {
|
||||
for (const [tier, elite, mod] of [[5, false, null], [6, true, null], [6, true, PROY]]) {
|
||||
const sk = skillOf(tier, elite, S2);
|
||||
const { h, u } = field({ tier, elite, mod, skill: 1 });
|
||||
@@ -151,9 +151,14 @@ test('S2 铜印 (31 / 32 s): stops attacking; DEF +80 % / +100 %, block +1; ever
|
||||
const sil = h.hooksOf('statusApplied').filter((c) => c.source === u && c.target === src && c.status === 'silence').slice(-1)[0];
|
||||
assert.ok(sil && Math.abs(sil.duration - 3) < 1e-9, `T${tier}: ${src.defId} silenced 3 s`);
|
||||
}
|
||||
// updated on purpose by the community report of 2026-10-06 (item 30): the official inverse_damage[magic] / nian_s_2 fire on
|
||||
// ON_TAKE_DAMAGE from an enemy source — a non-attack hit is answered too (it returned nothing up to 0.2.0); a 流失 is not
|
||||
const before = h.hooksOf('damaged').length;
|
||||
h.b.dealDamage(near, u, { amount: 100, type: 'phys' });
|
||||
assert.ok(!h.hooksOf('damaged').slice(before).some((c) => c.source === u), `T${tier}: a non-attack hit returns nothing`);
|
||||
assert.equal(h.hooksOf('damaged').slice(before).filter((c) => c.source === u && c.target === near).length, 1, `T${tier}: a non-attack hit is answered`);
|
||||
const beforeLoss = h.hooksOf('damaged').length;
|
||||
h.b.loseHp(u, 100, { source: near });
|
||||
assert.ok(!h.hooksOf('damaged').slice(beforeLoss).some((c) => c.source === u), `T${tier}: a 流失 returns nothing`);
|
||||
u.skill.extend(-999);
|
||||
h.run(0.1);
|
||||
const after = h.hooksOf('damaged').length;
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
// test/feedback5-operator-sfx.test.js — community report of 2026-10-06 (item 54) 「干员银灰的普通攻击的音效错误的使用了3技能期间
|
||||
// 的攻击音效」. The official banks of 银灰 (excel/audio_data.json): ON_ABILITY_HIT.char_172_svrash.combat (p_imp_spear_n — his
|
||||
// Default mode's Combat, the normal attack, which has no swing bank), ON_ABILITY_START / HIT .attack.2 (p_atk_silver_n /
|
||||
// p_imp_sword_n — his S3 mode; the charpack's modes are Default, S2, S3) and HIT .attack.1 (p_imp_sword_n — S2). The picker
|
||||
// took the numbered variants because their files end in _n. Now an operator whose default mode is the unsuffixed ability (a
|
||||
// plain attack / combat bank of any event) never takes a numbered variant (tools/assets/audio.mjs pickUnitSfx). The same
|
||||
// rule drops 雷蛇's S2 lightning impact, 初雪's S1-2 mode impact and 圣约送葬人's S3_End impact from their normal attacks.
|
||||
// Run: node --test test/feedback5-operator-sfx.test.js
|
||||
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { pickUnitSfx } from '../tools/assets/audio.mjs';
|
||||
|
||||
const P = (f) => [`player/${f.startsWith('p_imp') ? 'p_imp' : 'p_atk'}/${f}.mp3`];
|
||||
const op = (entries, projectile = {}) => pickUnitSfx(new Map(entries.map(([k, f]) => [k, P(f)])), { operator: true, projectile });
|
||||
|
||||
test('银灰: the normal attack is the Default mode\'s Combat — spear impact, no swing; the S3 swing and the S2 / S3 impact never', () => {
|
||||
const sfx = op([
|
||||
['ON_ABILITY_HIT.combat', 'p_imp_spear_n'],
|
||||
['ON_ABILITY_START.attack.2', 'p_atk_silver_n'],
|
||||
['ON_ABILITY_HIT.attack.2', 'p_imp_sword_n'],
|
||||
['ON_ABILITY_HIT.attack.1', 'p_imp_sword_n'],
|
||||
]);
|
||||
assert.deepEqual(sfx, { hit: P('p_imp_spear_n') });
|
||||
});
|
||||
|
||||
test('雷蛇 / 初雪 / 圣约送葬人: a plain swing, and no skill mode\'s impact on the normal attack', () => {
|
||||
assert.deepEqual(op([['ON_ABILITY_ON.attack', 'p_atk_pistol_n'], ['ON_ABILITY_HIT.attack.1', 'p_imp_lightning_n'], ['ON_ABILITY_START.attack.1', 'p_atk_lightning_n']]),
|
||||
{ attack: P('p_atk_pistol_n') }, '雷蛇 (attack.1 = S2)');
|
||||
assert.deepEqual(op([['ON_ABILITY_ON.attack', 'p_atk_shakebell_n'], ['ON_ABILITY_HIT.attack.1', 'p_imp_shakebell_n']]),
|
||||
{ attack: P('p_atk_shakebell_n') }, '初雪 (attack.1 = the S1-2 mode)');
|
||||
assert.deepEqual(op([['ON_ABILITY_ON.attack', 'p_atk_shotgunx_n'], ['ON_ABILITY_ON.attack.1', 'p_atk_shotgunx_d'], ['ON_ABILITY_START.attack.4', 'p_atk_bngel'], ['ON_ABILITY_HIT.attack.4', 'p_imp_bngel']]),
|
||||
{ attack: P('p_atk_shotgunx_n') }, '圣约送葬人 (attack.4 = S3_End)');
|
||||
// the operator's own projectile bank still serves when the plain ability has no impact bank
|
||||
assert.deepEqual(op([['ON_ABILITY_ON.attack', 'p_atk_x_n'], ['ON_ABILITY_HIT.attack.1', 'p_imp_x_s']], { hit: P('p_imp_x_n') }), { attack: P('p_atk_x_n'), hit: P('p_imp_x_n') });
|
||||
});
|
||||
|
||||
test('operators that number their default mode (attack.0 …) keep the earlier rule; a plain bank that is a skill-mode file does not count', () => {
|
||||
assert.deepEqual(op([['ON_ABILITY_START.attack.0', 'p_atk_y_n'], ['ON_ABILITY_HIT.attack.0', 'p_imp_y_n'], ['ON_ABILITY_START.attack.1', 'p_atk_y_n2']]),
|
||||
{ attack: P('p_atk_y_n'), hit: P('p_imp_y_n') });
|
||||
// 荒芜拉普兰德: the unsuffixed START bank is her _d file (a skill mode), her default is attack.0
|
||||
assert.deepEqual(op([['ON_ABILITY_START.attack.0', 'p_atk_whtolfdrksl_n'], ['ON_ABILITY_START.attack', 'p_atk_whtolfdrksl_d'], ['ON_ABILITY_ON.attack.2', 'p_atk_whtolfdrksl_h']]),
|
||||
{ attack: P('p_atk_whtolfdrksl_n') });
|
||||
});
|
||||
+25
-25
@@ -357,8 +357,8 @@
|
||||
["-","~3","device","trap_1105_accrate",null,null,100,1,3,0,0,0,0,0,null]
|
||||
],
|
||||
"enemies": {"enemy_1158_divman":[15,15,0,2017,57024],"enemy_1160_hvyslr":[2,2,0,5010,23040],"enemy_1161_tidmag":[1,1,0,1491,6912]},
|
||||
"hooks": [1,32,2070,168,168,255,260,1042,21,21,12,12,0,6047,106,8,18,0,1,21,1,0,3],
|
||||
"events": {"atk":215,"deploy":11,"die":21,"dmg":260,"engage":6,"fx":25,"layer":1,"skill":24,"spawn":31,"status":77},
|
||||
"hooks": [1,32,2070,168,168,265,270,1042,21,21,12,12,0,6047,106,8,18,0,1,21,1,0,3],
|
||||
"events": {"atk":215,"deploy":11,"die":21,"dmg":270,"engage":6,"fx":25,"layer":1,"skill":24,"spawn":31,"status":77},
|
||||
"fx": {"dilemma":1,"dodge":3,"explosion":5,"frostNova":2,"garrison":1,"levitate":7,"overclock":1,"shield":2,"slippery":1,"splash":2},
|
||||
"snaps": "01da0610 a11d4743 dacec57c 0fe89241 8359f8a8 3545ad4d 1d9e9ae3"
|
||||
},
|
||||
@@ -392,8 +392,8 @@
|
||||
["p1",8,"op","chess_char_4_26_b",0,"uniequip_002_bldsk",1522,1,55,0,0,17721,26801,37,9]
|
||||
],
|
||||
"enemies": {"enemy_1166_dusbr_2":[14,11,3,33134,133646],"enemy_1170_dushld_2":[4,1,3,37533,54717],"enemy_9011_acrefr":[4,1,0,75921,133613]},
|
||||
"hooks": [1,58,5700,890,890,1254,1237,4113,41,47,35,33,100,4048,235,79,22,6,1,41,0,0,17],
|
||||
"events": {"atk":1291,"deploy":36,"die":41,"dmg":1233,"engage":4,"fx":185,"heal":212,"leak":6,"skill":68,"spawn":30,"status":588},
|
||||
"hooks": [1,58,5700,890,890,1451,1434,4113,41,47,35,33,100,4048,235,79,22,6,1,41,0,0,17],
|
||||
"events": {"atk":1291,"deploy":36,"die":41,"dmg":1430,"engage":4,"fx":185,"heal":212,"leak":6,"skill":68,"spawn":30,"status":588},
|
||||
"fx": {"bandage":9,"dodge":17,"extraAttack":56,"garrisonGrant":1,"mote":35,"redistribute":30,"revive":25,"reweave":2,"sandChains":4,"shield":5,"spGift":1},
|
||||
"snaps": "7d5f326c b27b8121 c23f4b8e b11158be 745858a1 bc233c02 36600c75 96f7bb77 dd25f731 4dcd794a acc9ff4c c950f1bb dc098c51 333aecb6 1657b56a 3af3a6ec ae8a08a1 d78ef285 3ebb7cc5"
|
||||
},
|
||||
@@ -523,10 +523,10 @@
|
||||
["-","~3","device","trap_1105_accrate",null,null,100,1,3,0,0,0,0,0,null]
|
||||
],
|
||||
"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},
|
||||
"hooks": [1,27,2084,238,238,439,439,1730,18,18,8,7,0,7480,13,18,16,0,1,18,1,0,0],
|
||||
"events": {"atk":263,"deploy":8,"die":18,"dmg":431,"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"
|
||||
"snaps": "86cad855 f20e9695 1939f464 021173dc a7a02fb2 bf56e726 24bf526e"
|
||||
},
|
||||
"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",
|
||||
@@ -546,24 +546,24 @@
|
||||
"bossHpLeft": null,
|
||||
"rngDraws": 19,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {"p1":{"killed":30,"total":30,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":403782,"bossDmg":0,"heal":1898,"deaths":3,"layerGains":{}}},
|
||||
"players": {"p1":{"killed":30,"total":30,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":403710,"bossDmg":0,"heal":1898,"deaths":3,"layerGains":{}}},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_2_18_b",0,"uniequip_002_ashlok",1062.9,1,3,7,96672,2092,0,20,2],
|
||||
["p1",1,"op","chess_char_2_18_b",0,"uniequip_002_ashlok",1062.9,1,3,5,95295,2092,0,20,2],
|
||||
["p1",2,"op","chess_char_3_12_b",2,"uniequip_002_blemsh",3096,1,5,0,0,0,0,0,0],
|
||||
["p1",3,"op","chess_char_5_08_b",2,"uniequip_002_horn",610.48,1,7,11,69745,4063,1898,53,2],
|
||||
["p1",4,"op","chess_char_4_19_b",2,"uniequip_002_flamtl",2118,1,8,1,19858,0,0,17,2],
|
||||
["p1",5,"op","chess_char_1_19_b",1,"uniequip_002_wildmn",0,0,9,2,84656,1971,0,51,2],
|
||||
["p1",6,"op","chess_char_2_12_b",1,"uniequip_002_gravel",0,0,37,2,45811,4646,0,42,2],
|
||||
["p1",3,"op","chess_char_5_08_b",2,"uniequip_002_horn",610.48,1,7,10,66609,4063,1898,52,2],
|
||||
["p1",4,"op","chess_char_4_19_b",2,"uniequip_002_flamtl",2118,1,8,1,21184,0,0,17,2],
|
||||
["p1",5,"op","chess_char_1_19_b",1,"uniequip_002_wildmn",0,0,9,4,81694,1971,0,50,2],
|
||||
["p1",6,"op","chess_char_2_12_b",1,"uniequip_002_gravel",0,0,37,3,51889,4646,0,42,2],
|
||||
["p1",7,"op","chess_char_3_17_b",1,"uniequip_002_shotst",3441.6,1,4,7,84143,0,0,29,3],
|
||||
["p1",8,"op","chess_char_5_10_b",2,"uniequip_002_lisa",1480,1,6,0,2897,0,0,10,2],
|
||||
["-","~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_10124_uashld_2":[2,2,0,4508,124416],"enemy_1043_zomsbr":[23,23,0,20,147057],"enemy_1061_zomshd":[5,5,0,4181,132309]},
|
||||
"hooks": [1,41,2613,241,241,430,545,3492,33,33,15,13,0,5189,999,11,30,0,1,44,0,0,5],
|
||||
"events": {"atk":241,"deploy":9,"die":33,"dmg":425,"engage":7,"fx":54,"skill":28,"spawn":40,"status":121},
|
||||
"fx": {"aoe":24,"displace":15,"dodge":5,"flame":2,"overload":2,"riposte":1,"shield":2,"volley":3},
|
||||
"snaps": "5a72bba9 0659d371 e189ce8b f0de7f75 b7e6c462 bbd2a9c5 9a77b0eb d7d4a16d db3990ea"
|
||||
"enemies": {"enemy_10124_uashld_2":[2,2,0,4508,124416],"enemy_1043_zomsbr":[23,23,0,20,146972],"enemy_1061_zomshd":[5,5,0,4181,132323]},
|
||||
"hooks": [1,41,2613,239,239,479,594,3462,33,33,15,13,0,5189,999,11,30,0,1,43,0,0,5],
|
||||
"events": {"atk":239,"deploy":9,"die":33,"dmg":474,"engage":7,"fx":53,"skill":28,"spawn":40,"status":121},
|
||||
"fx": {"aoe":24,"displace":14,"dodge":5,"flame":2,"overload":2,"riposte":1,"shield":2,"volley":3},
|
||||
"snaps": "5a72bba9 62d17d06 7af61b0e de61a8e0 ff0837e9 7a7f5062 854b1dff e111ddbe ecf8b583"
|
||||
},
|
||||
"bond-kjeragShip-low": {
|
||||
"about": "谢拉格 low: tier 1 layers 1; chess_char_1_02_a chess_char_3_02_a chess_char_3_03_a chess_char_3_04_a chess_char_2_05_a chess_char_3_11_a chess_char_4_26_a chess_char_3_01_a",
|
||||
@@ -670,20 +670,20 @@
|
||||
"p1": {"killed":17,"total":17,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":94536,"bossDmg":0,"heal":0,"deaths":3,"layerGains":{"lateranoShip":3}}
|
||||
},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_3_06_a",1,null,3066.32,1,2,0,0,400,0,0,1],
|
||||
["p1",2,"op","chess_char_3_05_a",2,null,4697.91,1,4,3,8989,737,0,10,1],
|
||||
["p1",1,"op","chess_char_3_06_a",1,null,3066.32,1,2,0,450,400,0,0,1],
|
||||
["p1",2,"op","chess_char_3_05_a",2,null,4697.91,1,4,2,8751,737,0,9,1],
|
||||
["p1",3,"op","chess_char_1_01_a",1,null,223,1,7,2,13909,900,0,35,1],
|
||||
["p1",4,"op","chess_char_2_01_a",1,null,0,0,8,1,7351,1694,0,10,0],
|
||||
["p1",5,"op","chess_char_3_01_a",2,null,1071.8,1,1,7,6614,400,0,32,1],
|
||||
["p1",5,"op","chess_char_3_01_a",2,null,1071.8,1,1,8,6403,400,0,32,1],
|
||||
["p1",6,"op","chess_char_3_08_a",1,null,1194,1,3,0,5328,400,0,6,1],
|
||||
["p1",7,"op","chess_char_3_09_a",1,null,0,0,5,3,16254,1267,0,21,1],
|
||||
["p1",8,"op","chess_char_3_10_a",1,null,0,0,6,0,36092,1650,0,15,1]
|
||||
],
|
||||
"enemies": {"enemy_1267_nhpbr":[11,11,0,4668,57024],"enemy_1267_nhpbr_2":[5,5,0,1141,31680],"enemy_1272_nhtank":[1,1,0,1639,13824]},
|
||||
"hooks": [1,25,1853,134,134,488,488,0,20,20,7,4,15,7720,0,3,17,0,1,20,1,0,0],
|
||||
"events": {"atk":174,"deploy":8,"die":20,"dmg":488,"engage":7,"fx":28,"layer":1,"skill":11,"spawn":25,"status":1},
|
||||
"fx": {"buff":1,"displace":4,"garrison":1,"pull":4,"zone":18},
|
||||
"snaps": "c9571e9b 447301c4 c2a9024c efb0fbd5 235c33ca 49372e4b f842196b"
|
||||
"hooks": [1,25,1853,133,133,488,489,0,20,20,7,4,15,7720,0,3,17,0,1,20,1,0,0],
|
||||
"events": {"atk":173,"deploy":8,"die":20,"dmg":489,"engage":7,"fx":32,"layer":1,"skill":11,"spawn":25,"status":1},
|
||||
"fx": {"aoe":4,"buff":1,"displace":4,"garrison":1,"pull":4,"zone":18},
|
||||
"snaps": "c9571e9b 447301c4 c2a9024c efb0fbd5 235c33ca 426df9e4 5d2597e0"
|
||||
},
|
||||
"bond-lateranoShip-high": {
|
||||
"about": "拉特兰 high: tier 2 layers 999; chess_char_4_01_b chess_char_5_13_b chess_char_5_14_b chess_char_1_01_b chess_char_2_01_b chess_char_3_01_b chess_char_3_21_b chess_char_4_02_b",
|
||||
|
||||
@@ -2069,28 +2069,28 @@
|
||||
"bossHpLeft": null,
|
||||
"rngDraws": 0,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {"p1":{"killed":85,"total":99,"perfect":false,"leaks":14,"leaksUncounted":0,"coins":0,"dmg":1118348,"bossDmg":0,"heal":39314,"deaths":11,"layerGains":{}}},
|
||||
"players": {"p1":{"killed":85,"total":99,"perfect":false,"leaks":14,"leaksUncounted":0,"coins":0,"dmg":1118419,"bossDmg":0,"heal":39314,"deaths":11,"layerGains":{}}},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_5_diy1_a",0,null,2592,1,120,0,6323,2592,0,24,0],
|
||||
["p1",2,"op","chess_char_5_diy2_a",1,null,2592,1,113,1,21971,2592,1520,19,1],
|
||||
["p1",3,"op","chess_char_5_diy1_a",2,null,2592,1,111,2,58248,3442,0,36,1],
|
||||
["p1",4,"op","chess_char_5_diy2_b",0,"none",3228,1,121,12,109351,3228,0,74,1],
|
||||
["p1",5,"op","chess_char_5_diy1_b",1,"none",3032.16,1,12,19,263069,21223,23687,95,6],
|
||||
["p1",5,"op","chess_char_5_diy1_b",1,"none",3032.16,1,12,19,262996,21223,23687,95,6],
|
||||
["p1",6,"op","chess_char_5_diy2_b",2,"none",732.33,1,93,16,190077,6715,0,82,2],
|
||||
["p1",7,"op","chess_char_5_diy1_b",0,"uniequip_002_hsgma2",27.21,1,75,12,127942,6809,0,83,1],
|
||||
["p1",8,"op","chess_char_5_diy2_b",1,"uniequip_002_hsgma2",1,1,3,5,67826,7203,6378,42,4],
|
||||
["p1",9,"op","chess_char_5_diy1_b",2,"uniequip_002_hsgma2",0,0,5,2,79393,4086,0,44,2],
|
||||
["p1",7,"op","chess_char_5_diy1_b",0,"uniequip_002_hsgma2",27.21,1,75,12,128015,6809,0,83,1],
|
||||
["p1",8,"op","chess_char_5_diy2_b",1,"uniequip_002_hsgma2",1,1,3,5,67837,7203,6378,42,4],
|
||||
["p1",9,"op","chess_char_5_diy1_b",2,"uniequip_002_hsgma2",0,0,5,2,79453,4086,0,44,2],
|
||||
["p1",10,"op","chess_char_6_diy1_a",0,null,0,0,118,0,1484,5185,605,43,0],
|
||||
["p1",11,"op","chess_char_6_diy2_a",1,null,2592,1,119,2,62301,2644,6236,42,2],
|
||||
["p1",12,"op","chess_char_6_diy1_a",2,null,0,0,11,14,130362,3304,888,80,2],
|
||||
["-","~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_1010_demon":[42,38,4,21593,454505],"enemy_1320_wdrrl_2":[12,6,5,44200,309455],"enemy_1422_lrsldr_2":[45,41,4,3230,354388]},
|
||||
"hooks": [1,121,6900,1369,1369,2970,2970,1467,96,109,22,20,0,11502,695,97,99,13,1,96,0,0,0],
|
||||
"events": {"atk":1482,"deploy":20,"die":96,"dmg":2756,"engage":12,"fx":893,"heal":574,"leak":13,"skill":42,"spawn":113,"status":264},
|
||||
"enemies": {"enemy_1010_demon":[42,38,4,21593,454505],"enemy_1320_wdrrl_2":[12,6,5,44200,309526],"enemy_1422_lrsldr_2":[45,41,4,3230,354388]},
|
||||
"hooks": [1,121,6900,1369,1369,2973,2973,1467,96,109,22,20,0,11502,695,97,99,13,1,96,0,0,0],
|
||||
"events": {"atk":1482,"deploy":20,"die":96,"dmg":2759,"engage":12,"fx":893,"heal":574,"leak":13,"skill":42,"spawn":113,"status":264},
|
||||
"fx": {"counter":154,"explode":10,"strike":695,"undying":21,"zone":13},
|
||||
"snaps": "3178290b a1e79565 3e8d348d 5df93583 8eaac70b 4fd00ffb c91cde31 fe3a467d bc262795 604cd633 bbf789d3 7026fba9 19512d4c 51ebad00 91169fd0 b7c98067 f6a5313f f592cfc9 b78c6faf 3522036e 0ff4b89b dc781b7a c895cf51"
|
||||
"snaps": "3178290b a1e79565 3e8d348d 57d8c0ec 693d384c 31d69b16 e600d9d0 18d1f8ba 6b8f73c6 556d017a e6dbe7c7 a8f52db3 e86e3395 6f0b94e1 5de77001 0f5c8e43 2d22cb67 9d427bb7 b213b370 79e1e980 6dbddd86 d243d612 6b2385d8"
|
||||
},
|
||||
"diy-052": {
|
||||
"about": "6_diy1_b=hsgma2/S1 6_diy2_b=hsgma2/S2 6_diy1_b=hsgma2/S3 6_diy2_b=hsgma2/S1/002_hsgma2 6_diy1_b=hsgma2/S2/002_hsgma2 6_diy2_b=hsgma2/S3/002_hsgma2 5_diy1_a=thumpy/S1 5_diy2_a=thumpy/S2 5_diy1_a=thumpy/S3 5_diy2_b=thumpy/S1 5_diy1_b=thumpy/S2 5_diy2_b=thumpy/S3",
|
||||
|
||||
+64
-65
@@ -226,12 +226,12 @@
|
||||
"killed": 5,
|
||||
"total": 7,
|
||||
"unspawned": 0,
|
||||
"bossHpLeft": 2859626,
|
||||
"bossHpLeft": 2859549,
|
||||
"rngDraws": 58,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {"p1":{"killed":5,"total":7,"perfect":false,"leaks":2,"leaksUncounted":0,"coins":0,"dmg":299098,"bossDmg":134272,"heal":35078,"deaths":3,"layerGains":{}}},
|
||||
"players": {"p1":{"killed":5,"total":7,"perfect":false,"leaks":2,"leaksUncounted":0,"coins":0,"dmg":299175,"bossDmg":134349,"heal":35078,"deaths":3,"layerGains":{}}},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_4_17_b",1,"uniequip_002_hsguma",1986.83,1,18,0,1827,13433,11108,37,0],
|
||||
["p1",1,"op","chess_char_4_17_b",1,"uniequip_002_hsguma",1986.83,1,18,0,1903,13433,11108,37,0],
|
||||
["p1",2,"op","chess_char_4_18_b",1,"uniequip_002_mudrok",6104,1,4,0,37730,0,0,35,2],
|
||||
["p1",3,"op","chess_char_4_23_b",2,"uniequip_002_gvial2",2811,1,6,0,16657,4105,2581,25,3],
|
||||
["p1",4,"op","chess_char_4_19_b",2,"uniequip_002_flamtl",2118,1,7,1,21419,5053,804,44,5],
|
||||
@@ -242,11 +242,11 @@
|
||||
["p1",9,"op","chess_char_4_25_b",2,"uniequip_002_cetsyr",1671,1,3,0,0,0,305,0,3],
|
||||
["p1",10,"op","chess_char_4_26_b",0,"uniequip_002_bldsk",1522,1,5,0,0,1296,18849,34,3]
|
||||
],
|
||||
"enemies": {"enemy_1249_lysdb_2":[5,5,0,9688,107495],"enemy_1430_lrrook":[2,0,2,0,62729],"enemy_9017_achunt":[1,0,0,20116,140374]},
|
||||
"hooks": [1,21,6000,385,385,1023,1424,4394,8,10,26,25,0,13111,66,5,8,2,1,11,0,3,1],
|
||||
"events": {"atk":403,"deploy":13,"die":8,"dmg":1420,"engage":7,"fx":263,"heal":40,"leak":2,"skill":54,"spawn":18,"status":411},
|
||||
"fx": {"bandage":3,"block":3,"burst":3,"charge":7,"dodge":1,"featherArrow":1,"flame":5,"garrisonGrant":1,"healField":1,"jungleSoul":3,"mote":102,"redistribute":45,"reweave":3,"riposte":1,"rockslide":2,"sandChains":3,"sandChainsCharged":2,"shieldBreak":9,"slash":55,"spGift":5,"thorns":5,"truesilver":3},
|
||||
"snaps": "cfcfbf4d 2e36f4c4 d86de811 0291110d a7bef78a 57650c6e 1788104a a346a2f4 ac587ca9 03b1a538 d546b910 cb6e362b 1d445bed 6fb308e1 46e3cb1a 26076bc9 1f093b66 58befce9 abcdba0e 4123d12c"
|
||||
"enemies": {"enemy_1249_lysdb_2":[5,5,0,9688,107495],"enemy_1430_lrrook":[2,0,2,0,62729],"enemy_9017_achunt":[1,0,0,20116,140451]},
|
||||
"hooks": [1,21,6000,385,385,1025,1426,4394,8,10,26,25,0,13111,66,5,8,2,1,11,0,3,1],
|
||||
"events": {"atk":403,"deploy":13,"die":8,"dmg":1422,"engage":7,"fx":265,"heal":40,"leak":2,"skill":54,"spawn":18,"status":411},
|
||||
"fx": {"bandage":3,"block":3,"burst":3,"charge":7,"dodge":1,"featherArrow":1,"flame":5,"garrisonGrant":1,"healField":1,"jungleSoul":3,"mote":102,"redistribute":45,"reweave":3,"riposte":1,"rockslide":2,"sandChains":3,"sandChainsCharged":2,"shieldBreak":9,"slash":55,"spGift":5,"thorns":7,"truesilver":3},
|
||||
"snaps": "cfcfbf4d 2e36f4c4 d86de811 0291110d 4f29388b e434804a d530cfc9 d89605a6 4a75903e ddfff266 80cd13ba 850aef17 c3b00acb 56dc7d74 bd189bf7 7feda4fd 3278f83b a5ac2ad0 e0909387 8bd04ac0"
|
||||
},
|
||||
"boss-boss_3-pair": {
|
||||
"about": "假想敌:管 pair pool 4000000: chess_char_6_03_b chess_char_6_06_b chess_char_6_07_b chess_char_6_01_b chess_char_6_02_b chess_char_6_04_b chess_char_6_05_b chess_char_6_08_b chess_char_6_09_b chess_char_6_11_b token_10017_skadi2_dedant | chess_char_6_15_b chess_char_6_19_b chess_char_5_01_b chess_char_6_17_b chess_char_6_12_b chess_char_6_13_b chess_char_6_14_b chess_char_6_16_b chess_char_6_18_b chess_char_6_20_b",
|
||||
@@ -422,15 +422,15 @@
|
||||
"killed": 12,
|
||||
"total": 14,
|
||||
"unspawned": 0,
|
||||
"bossHpLeft": 7548877,
|
||||
"bossHpLeft": 7548291,
|
||||
"rngDraws": 541,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {
|
||||
"p1": {"killed":12,"total":14,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":893986,"bossDmg":308902,"heal":31619,"deaths":19,"layerGains":{}},
|
||||
"p1": {"killed":12,"total":14,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":894572,"bossDmg":309488,"heal":31619,"deaths":19,"layerGains":{}},
|
||||
"p2": {"killed":0,"total":0,"perfect":false,"leaks":2,"leaksUncounted":0,"coins":0,"dmg":962354,"bossDmg":542221,"heal":6389,"deaths":22,"layerGains":{}}
|
||||
},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_5_19_b",2,"uniequip_002_mlynar",0,0,57,1,144856,8141,327,24,1],
|
||||
["p1",1,"op","chess_char_5_19_b",2,"uniequip_002_mlynar",0,0,57,1,145442,8141,327,24,1],
|
||||
["p1",2,"op","chess_char_4_01_b",2,"uniequip_002_rmixer",0,0,62,1,21035,11064,1107,16,2],
|
||||
["p1",3,"op","chess_char_5_14_b",1,"none",0,0,63,1,36157,11533,601,6,7],
|
||||
["p1",4,"op","chess_char_5_17_b",1,"uniequip_002_f12yin",0,0,67,0,13062,13688,855,15,1],
|
||||
@@ -453,9 +453,9 @@
|
||||
["p2",21,"token","token_10041_cathy_catsld",null,null,100,1,21,0,0,0,0,0,null],
|
||||
["p2",22,"token","token_10041_cathy_catsld",null,null,100,1,22,0,0,0,0,0,null]
|
||||
],
|
||||
"enemies": {"enemy_1010_demon":[4,4,0,0,200612],"enemy_1438_dspred":[10,8,2,32559,804605],"enemy_1521_dslily":[1,0,0,96332,851123]},
|
||||
"hooks": [1,70,6000,1061,1132,2768,2891,6042,55,61,122,121,16,31476,1150,23,15,2,1,56,0,24,2],
|
||||
"events": {"atk":1283,"deploy":55,"die":59,"dmg":2881,"engage":17,"fx":792,"heal":216,"leak":2,"skill":243,"spawn":37,"status":834},
|
||||
"enemies": {"enemy_1010_demon":[4,4,0,0,200612],"enemy_1438_dspred":[10,8,2,32559,804605],"enemy_1521_dslily":[1,0,0,96332,851709]},
|
||||
"hooks": [1,70,6000,1061,1132,2771,2894,6042,55,61,122,121,16,31476,1150,23,15,2,1,56,0,24,2],
|
||||
"events": {"atk":1283,"deploy":55,"die":59,"dmg":2884,"engage":17,"fx":792,"heal":216,"leak":2,"skill":243,"spawn":37,"status":834},
|
||||
"fx": {
|
||||
"aoe": 20,
|
||||
"appear": 5,
|
||||
@@ -493,7 +493,7 @@
|
||||
"weightless": 4,
|
||||
"zone": 261
|
||||
},
|
||||
"snaps": "f65be30a 3fab4736 85e2bb50 91bfa19d 93214291 4b83b01b 615be497 b793dacf d713f4bf a63a221d c2db01e9 0546ff9b 17661f26 edf65cc8 addd19b1 59530186 37cddc6b 2c477685 7e246006 61595031"
|
||||
"snaps": "f65be30a 3fab4736 85e2bb50 91bfa19d c5eddb52 fd7e0416 d740b75f f9939846 6d1868e0 c2e99d1c 1f303961 325732e8 03c81744 6172154b c9b3558e c8446574 af78381a b76cfb73 6fc7fa37 d28f2751"
|
||||
},
|
||||
"boss-boss_4-solo": {
|
||||
"about": "盐风主教昆图斯 solo pool 4200000: chess_char_4_17_b chess_char_4_18_b chess_char_4_23_b chess_char_4_19_b chess_char_4_22_b chess_char_4_20_b chess_char_4_21_b chess_char_4_24_b chess_char_4_25_b chess_char_4_26_b",
|
||||
@@ -510,12 +510,12 @@
|
||||
"killed": 3,
|
||||
"total": 7,
|
||||
"unspawned": 0,
|
||||
"bossHpLeft": 3784802,
|
||||
"bossHpLeft": 3782696,
|
||||
"rngDraws": 93,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {"p1":{"killed":3,"total":7,"perfect":false,"leaks":4,"leaksUncounted":0,"coins":0,"dmg":684711,"bossDmg":415198,"heal":102513,"deaths":4,"layerGains":{}}},
|
||||
"players": {"p1":{"killed":3,"total":7,"perfect":false,"leaks":4,"leaksUncounted":0,"coins":0,"dmg":686816,"bossDmg":417304,"heal":102513,"deaths":4,"layerGains":{}}},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_4_17_b",1,"uniequip_002_hsguma",2960.13,1,4,0,24792,17230,20988,31,0],
|
||||
["p1",1,"op","chess_char_4_17_b",1,"uniequip_002_hsguma",2960.13,1,4,0,26897,17230,20988,31,0],
|
||||
["p1",2,"op","chess_char_4_18_b",1,"uniequip_002_mudrok",5988.52,1,22,1,44133,24266,18046,14,7],
|
||||
["p1",3,"op","chess_char_4_23_b",2,"uniequip_002_gvial2",2811,1,21,2,195258,38908,13125,40,1],
|
||||
["p1",4,"op","chess_char_4_19_b",2,"uniequip_002_flamtl",3388.8,1,9,0,0,5388,0,0,0],
|
||||
@@ -528,11 +528,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_1010_demon_2":[2,2,0,6788,107495],"enemy_1438_dspred":[5,1,4,35508,162017],"enemy_1521_dslily":[1,0,0,69173,415198]},
|
||||
"hooks": [1,23,6000,585,585,998,1144,8285,7,11,30,30,0,13584,137,13,8,4,1,7,0,31,0],
|
||||
"events": {"atk":794,"deploy":13,"die":7,"dmg":1126,"engage":6,"fx":343,"heal":107,"leak":4,"skill":62,"spawn":20,"status":525},
|
||||
"fx": {"bandage":4,"block":19,"burst":31,"camouflage":1,"featherArrow":5,"garrisonGrant":1,"grow":1,"healField":2,"jungleSoul":1,"mote":68,"redistribute":45,"reweave":3,"rockfall":18,"rockslide":7,"sandChains":5,"shieldBreak":18,"slash":46,"spGift":3,"tentacle":6,"thorns":51,"tide":5,"truesilver":3},
|
||||
"snaps": "501b4dd4 877a4d48 68f61133 0c4f2d25 66d31d7d 2f1febdd 16d86817 be1ddbe8 895b5c6a ce7ab97a 2c2c9cff e0efdfa3 98ac6cb8 133c9069 5d797196 35eb846a 463c1d7b 0485eea7 2025f7bd a77ca075"
|
||||
"enemies": {"enemy_1010_demon_2":[2,2,0,6788,107495],"enemy_1438_dspred":[5,1,4,35508,162017],"enemy_1521_dslily":[1,0,0,69173,417304]},
|
||||
"hooks": [1,23,6000,585,585,1005,1151,8285,7,11,30,30,0,13584,137,13,8,4,1,7,0,31,0],
|
||||
"events": {"atk":794,"deploy":13,"die":7,"dmg":1133,"engage":6,"fx":350,"heal":107,"leak":4,"skill":62,"spawn":20,"status":525},
|
||||
"fx": {"bandage":4,"block":19,"burst":31,"camouflage":1,"featherArrow":5,"garrisonGrant":1,"grow":1,"healField":2,"jungleSoul":1,"mote":68,"redistribute":45,"reweave":3,"rockfall":18,"rockslide":7,"sandChains":5,"shieldBreak":18,"slash":46,"spGift":3,"tentacle":6,"thorns":58,"tide":5,"truesilver":3},
|
||||
"snaps": "501b4dd4 877a4d48 68f61133 a14c3141 7de19e3d 43935a2d 5e496d64 5114c159 873c19da e4c0f03d 378dbfbd 9372ab33 7c8921ba 1cba8560 7342781f 4e42938d c1a0ccea e8e4755b 44327e56 1337e35b"
|
||||
},
|
||||
"boss-boss_5-pair": {
|
||||
"about": "卢西恩,“猩红血钻” pair pool 1560000: chess_char_6_03_b chess_char_6_06_b chess_char_6_07_b chess_char_6_01_b chess_char_6_02_b chess_char_6_04_b chess_char_6_05_b chess_char_6_08_b chess_char_6_09_b chess_char_6_11_b token_10017_skadi2_dedant token_10030_mlyss_wtrman | chess_char_6_15_b chess_char_6_19_b chess_char_5_01_b chess_char_6_17_b chess_char_6_12_b chess_char_6_13_b chess_char_6_14_b chess_char_6_16_b chess_char_6_18_b chess_char_6_20_b",
|
||||
@@ -965,18 +965,18 @@
|
||||
"rngDraws": 468,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {
|
||||
"p1": {"killed":12,"total":18,"perfect":false,"leaks":3,"leaksUncounted":0,"coins":0,"dmg":1813792,"bossDmg":944377,"heal":33830,"deaths":17,"layerGains":{}},
|
||||
"p1": {"killed":12,"total":18,"perfect":false,"leaks":3,"leaksUncounted":0,"coins":0,"dmg":1815171,"bossDmg":944377,"heal":33830,"deaths":17,"layerGains":{}},
|
||||
"p2": {"killed":0,"total":0,"perfect":false,"leaks":1,"leaksUncounted":0,"coins":0,"dmg":1106705,"bossDmg":824962,"heal":6361,"deaths":24,"layerGains":{}}
|
||||
},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_5_19_b",2,"uniequip_002_mlynar",7814,1,87,2,99556,22699,524,33,2],
|
||||
["p1",1,"op","chess_char_5_19_b",2,"uniequip_002_mlynar",7814,1,87,2,101550,22699,524,33,2],
|
||||
["p1",2,"op","chess_char_4_01_b",2,"uniequip_002_rmixer",7074,1,76,0,5363,9113,632,5,1],
|
||||
["p1",3,"op","chess_char_5_14_b",1,"none",3988,1,82,0,51953,11489,1912,18,7],
|
||||
["p1",4,"op","chess_char_5_17_b",1,"uniequip_002_f12yin",5476,1,83,2,64073,18040,1691,23,2],
|
||||
["p1",5,"op","chess_char_5_15_b",1,"uniequip_002_thorn2",0,0,71,0,683642,5223,11602,89,10],
|
||||
["p1",6,"op","chess_char_5_20_b",2,"uniequip_002_aglina",0,0,72,2,377669,13930,191,24,2],
|
||||
["p1",7,"op","chess_char_5_21_b",1,"uniequip_002_sntlla",0,0,54,0,1445,6516,0,3,1],
|
||||
["p1",8,"op","chess_char_5_22_b",1,"uniequip_002_nymph",2469.42,1,69,3,433079,3975,0,26,9],
|
||||
["p1",8,"op","chess_char_5_22_b",1,"uniequip_002_nymph",2469.42,1,69,3,432464,3975,0,26,9],
|
||||
["p1",9,"op","chess_char_5_23_b",1,"uniequip_002_reckpr",0,0,70,0,0,8508,17279,15,1],
|
||||
["p1",10,"op","chess_char_4_02_b",2,"uniequip_002_mostma",2175.85,1,79,1,97012,7994,0,24,2],
|
||||
["p2",11,"op","chess_char_4_11_b",1,"uniequip_002_cathy",0,0,78,0,0,8375,179,0,2],
|
||||
@@ -993,7 +993,7 @@
|
||||
["p2",22,"token","token_10041_cathy_catsld",null,null,100,1,22,0,0,0,0,0,null]
|
||||
],
|
||||
"enemies": {
|
||||
"enemy_10027_vtsk": [6,1,3,119156,802040],
|
||||
"enemy_10027_vtsk": [6,1,3,119156,803419],
|
||||
"enemy_1005_yokai": [4,4,0,0,1600],
|
||||
"enemy_1229_darmy_2": [8,7,1,4411,292434],
|
||||
"enemy_9013_acstmk_2": [1,0,0,46945,1770379],
|
||||
@@ -1001,8 +1001,8 @@
|
||||
"enemy_9015_acstmb": [3,2,0,8822,56064],
|
||||
"enemy_9016_acstmr": [8,7,0,0,38]
|
||||
},
|
||||
"hooks": [1,87,6000,794,795,2574,2713,4313,66,71,94,93,5,24475,892,16,35,4,1,64,0,6,12],
|
||||
"events": {"atk":915,"deploy":52,"die":67,"dmg":2712,"engage":17,"fx":539,"heal":101,"leak":4,"skill":187,"spawn":57,"status":666},
|
||||
"hooks": [1,87,6000,794,795,2582,2721,4313,66,71,94,93,5,24475,892,16,35,4,1,64,0,6,12],
|
||||
"events": {"atk":915,"deploy":52,"die":67,"dmg":2720,"engage":17,"fx":539,"heal":101,"leak":4,"skill":187,"spawn":57,"status":666},
|
||||
"fx": {
|
||||
"aoe": 26,
|
||||
"appear": 9,
|
||||
@@ -1045,7 +1045,7 @@
|
||||
"weightless": 2,
|
||||
"zone": 178
|
||||
},
|
||||
"snaps": "1b4d1c90 fb246339 f1dd6c3a f6d6e05e 52ebafed 068e9a5e 29f24601 932c2a97 8f79d53e 376fa541 2d8ce13d e0ab9b09 87adcf7a a8ebe0bd 0714a18a 50636ff0 5ed52282 d05808ac 964062c6 c6a3ead9"
|
||||
"snaps": "1b4d1c90 f1b90f93 dcdc842b 5500cbdd 028ee90f b4a52129 530c22f1 40bee116 88d91426 ebe268fb af583f26 fe597e9b deff454b 7478d5ee b4c5cbc9 c01cf5af 8e3e8db3 fccef60c fee348dc 919eeb8a"
|
||||
},
|
||||
"hidden-boss_8-solo": {
|
||||
"about": "假想敌:胄 solo pool 7200000: chess_char_4_17_b chess_char_4_18_b chess_char_4_23_b chess_char_4_19_b chess_char_4_22_b chess_char_4_20_b chess_char_4_21_b chess_char_4_24_b chess_char_4_25_b chess_char_4_26_b",
|
||||
@@ -1062,12 +1062,12 @@
|
||||
"killed": 6,
|
||||
"total": 16,
|
||||
"unspawned": 0,
|
||||
"bossHpLeft": 6810440,
|
||||
"bossHpLeft": 6810274,
|
||||
"rngDraws": 230,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {"p1":{"killed":6,"total":16,"perfect":false,"leaks":10,"leaksUncounted":0,"coins":0,"dmg":430027,"bossDmg":389560,"heal":30839,"deaths":21,"layerGains":{}}},
|
||||
"players": {"p1":{"killed":6,"total":16,"perfect":false,"leaks":10,"leaksUncounted":0,"coins":0,"dmg":430335,"bossDmg":389726,"heal":30839,"deaths":21,"layerGains":{}}},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_4_17_b",1,"uniequip_002_hsguma",0,0,6,1,366,8626,0,14,0],
|
||||
["p1",1,"op","chess_char_4_17_b",1,"uniequip_002_hsguma",0,0,6,1,673,8626,0,14,0],
|
||||
["p1",2,"op","chess_char_4_18_b",1,"uniequip_002_mudrok",0,0,36,3,17870,18617,6409,9,6],
|
||||
["p1",3,"op","chess_char_4_23_b",2,"uniequip_002_gvial2",0,0,7,0,0,2811,0,0,0],
|
||||
["p1",4,"op","chess_char_4_19_b",2,"uniequip_002_flamtl",0,0,53,0,0,12061,0,0,0],
|
||||
@@ -1083,19 +1083,19 @@
|
||||
["-","~4","device","trap_1105_accrate",null,null,100,1,4,0,0,0,0,0,null]
|
||||
],
|
||||
"enemies": {
|
||||
"enemy_10027_vtsk": [3,0,3,31231,18110],
|
||||
"enemy_10027_vtsk": [3,0,3,31231,18252],
|
||||
"enemy_1005_yokai": [4,2,2,0,800],
|
||||
"enemy_1197_sfshu": [3,2,1,80,19661],
|
||||
"enemy_1198_msfshu": [6,2,4,0,9],
|
||||
"enemy_9013_acstmk_2": [1,0,0,38158,389560],
|
||||
"enemy_9013_acstmk_2": [1,0,0,38158,389726],
|
||||
"enemy_9014_acstma": [3,2,0,0,1865],
|
||||
"enemy_9015_acstmb": [4,3,0,4799,0],
|
||||
"enemy_9016_acstmr": [6,6,0,0,22]
|
||||
},
|
||||
"hooks": [1,56,6000,313,313,552,552,869,38,48,16,16,0,5467,46,4,30,10,1,32,0,0,0],
|
||||
"events": {"atk":365,"deploy":22,"die":38,"dmg":545,"engage":5,"fx":181,"heal":79,"leak":10,"skill":33,"spawn":44,"status":141},
|
||||
"fx": {"bandage":1,"beam":33,"blink":11,"block":8,"charge":6,"explode":9,"garrisonGrant":1,"healField":4,"mote":4,"redistribute":5,"reweave":1,"rockslide":6,"sandChains":1,"shell":6,"shieldBreak":7,"slash":57,"spGift":5,"summon":6,"telegraph":3,"thorns":4,"truesilver":3},
|
||||
"snaps": "c4c16f4a ddad744b 0ec6d0a5 6cb40df0 b236a93e cb798820 ca99623b cba70a39 80d89436 d2c74f1b fc6586fc acf0d6cf 27a8ebae 816ae142 dae36003 48c83f46 040cf0ab f675868b bf456a17 84add322"
|
||||
"hooks": [1,56,6000,313,313,565,565,869,38,48,16,16,0,5467,46,4,30,10,1,32,0,0,0],
|
||||
"events": {"atk":365,"deploy":22,"die":38,"dmg":558,"engage":5,"fx":194,"heal":79,"leak":10,"skill":33,"spawn":44,"status":141},
|
||||
"fx": {"bandage":1,"beam":33,"blink":11,"block":8,"charge":6,"explode":9,"garrisonGrant":1,"healField":4,"mote":4,"redistribute":5,"reweave":1,"rockslide":6,"sandChains":1,"shell":6,"shieldBreak":7,"slash":57,"spGift":5,"summon":6,"telegraph":3,"thorns":17,"truesilver":3},
|
||||
"snaps": "c4c16f4a e0f36869 c8e410ce 7b59826b 31eb0f33 df2f84b5 c35f8fe9 05bd5883 08426b21 63c36146 97833e0e e6aa0e4d b1857582 0aaabec8 0bbeefa0 3205278b 4f41f8a5 c2d70b82 b6c40c16 ebd2bc44"
|
||||
},
|
||||
"hidden-boss_9-pair": {
|
||||
"about": "假想敌:铳 pair pool 5600000: chess_char_6_03_b chess_char_6_06_b chess_char_6_07_b chess_char_6_01_b chess_char_6_02_b chess_char_6_04_b chess_char_6_05_b chess_char_6_08_b chess_char_6_09_b chess_char_6_11_b token_10017_skadi2_dedant token_10030_mlyss_wtrman | chess_char_6_15_b chess_char_6_19_b chess_char_5_01_b chess_char_6_17_b chess_char_6_12_b chess_char_6_13_b chess_char_6_14_b chess_char_6_16_b chess_char_6_18_b chess_char_6_20_b",
|
||||
@@ -1228,38 +1228,37 @@
|
||||
"killed": 3,
|
||||
"total": 3,
|
||||
"unspawned": 0,
|
||||
"bossHpLeft": 1870565,
|
||||
"rngDraws": 124,
|
||||
"bossHpLeft": 1903562,
|
||||
"rngDraws": 67,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {"p1":{"killed":3,"total":3,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":2969443,"bossDmg":929435,"heal":76069,"deaths":5,"layerGains":{}}},
|
||||
"players": {"p1":{"killed":3,"total":3,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":2843148,"bossDmg":896438,"heal":73550,"deaths":3,"layerGains":{}}},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_5_08_b",2,"uniequip_002_horn",2775,1,1,0,377438,9366,0,127,4],
|
||||
["p1",2,"op","chess_char_5_11_b",1,"uniequip_002_demkni",4794.8,1,3,0,832,3417,28568,44,33],
|
||||
["p1",3,"op","chess_char_5_05_b",2,"uniequip_002_ulpia",10629,1,36,0,414083,36990,19701,39,5],
|
||||
["p1",4,"op","chess_char_5_06_b",2,"uniequip_002_etlchi",2567.95,1,7,1,1490203,17115,16047,201,5],
|
||||
["p1",5,"op","chess_char_5_13_b",1,"uniequip_002_ghost2",3364.8,1,9,1,118420,12547,3364,79,3],
|
||||
["p1",6,"op","chess_char_5_07_b",2,"uniequip_002_surtr",2524.94,1,39,0,15153,19432,3930,10,2],
|
||||
["p1",7,"op","chess_char_5_02_b",2,"uniequip_002_titi",1439,1,5,0,0,0,0,0,0],
|
||||
["p1",8,"op","chess_char_5_03_b",2,"uniequip_002_blaze2",968.1,1,6,0,289738,1471,967,189,6],
|
||||
["p1",9,"op","chess_char_5_10_b",2,"uniequip_002_lisa",1480,1,35,0,19621,10891,3491,28,6],
|
||||
["p1",10,"op","chess_char_5_12_b",0,"uniequip_002_dusk",1787,1,2,1,243954,0,0,53,41],
|
||||
["p1","~1","token","token_10039_ulpia_block",null,null,3485,0,17,0,0,15,0,0,null],
|
||||
["p1","~2","token","token_10039_ulpia_block",null,null,3350,0,24,0,0,150,0,0,null],
|
||||
["p1","~3","token","token_10039_ulpia_block",null,null,3335,0,31,0,0,165,0,0,null]
|
||||
["p1",1,"op","chess_char_5_08_b",2,"uniequip_002_horn",2698.4,1,1,0,324837,9374,0,127,4],
|
||||
["p1",2,"op","chess_char_5_11_b",1,"uniequip_002_demkni",4804.8,1,3,0,848,2750,31550,44,34],
|
||||
["p1",3,"op","chess_char_5_05_b",2,"uniequip_002_ulpia",6503.23,1,31,0,255230,37295,14964,28,4],
|
||||
["p1",4,"op","chess_char_5_06_b",2,"uniequip_002_etlchi",3543.16,1,7,2,1502942,13705,13608,201,5],
|
||||
["p1",5,"op","chess_char_5_13_b",1,"uniequip_002_ghost2",3364.8,1,9,1,107792,11970,2438,65,2],
|
||||
["p1",6,"op","chess_char_5_07_b",2,"uniequip_002_surtr",238.16,1,25,0,8629,21618,5871,17,2],
|
||||
["p1",7,"op","chess_char_5_02_b",2,"uniequip_002_titi",1439,1,5,0,6082,0,2705,17,1],
|
||||
["p1",8,"op","chess_char_5_03_b",2,"uniequip_002_blaze2",351.58,1,6,0,364837,2591,1471,188,6],
|
||||
["p1",9,"op","chess_char_5_10_b",2,"uniequip_002_lisa",1480,1,24,0,15428,5383,943,40,5],
|
||||
["p1",10,"op","chess_char_5_12_b",0,"uniequip_002_dusk",1777,1,2,0,256524,80,0,53,41],
|
||||
["p1","~1","token","token_10039_ulpia_block",null,null,3350,0,20,0,0,150,0,0,null],
|
||||
["p1","~2","token","token_10039_ulpia_block",null,null,3335,0,28,0,0,165,0,0,null]
|
||||
],
|
||||
"enemies": {
|
||||
"enemy_10067_ftsjc": [1,1,0,1161,21565],
|
||||
"enemy_5601_entlec": [7,6,0,0,174538],
|
||||
"enemy_9007_acelem": [2,2,0,747,119439],
|
||||
"enemy_9017_achunt_2": [1,0,0,33211,929435],
|
||||
"enemy_9018_actrpa": [1,0,0,16277,517062],
|
||||
"enemy_9019_actrpb": [1,0,0,18530,477352],
|
||||
"enemy_9020_actrpc": [1,0,0,15909,730051]
|
||||
"enemy_5601_entlec": [6,6,0,0,166866],
|
||||
"enemy_9007_acelem": [2,2,0,1054,119439],
|
||||
"enemy_9017_achunt_2": [1,0,0,28371,896438],
|
||||
"enemy_9018_actrpa": [1,0,0,14779,508719],
|
||||
"enemy_9019_actrpb": [1,0,0,19659,453678],
|
||||
"enemy_9020_actrpc": [1,0,0,17888,676442]
|
||||
},
|
||||
"hooks": [1,40,6000,876,876,3547,8777,6397,14,19,105,102,118,25207,1875,10,14,0,1,109,0,2,0],
|
||||
"events": {"atk":1409,"deploy":26,"die":19,"dmg":8204,"engage":9,"fx":850,"heal":383,"skill":207,"spawn":27,"status":303},
|
||||
"fx": {"anchor":5,"aoe":2,"beam":20,"burst":2,"candle":7,"charge":7,"dash":12,"downed":1,"ember":2,"explode":1,"healAoe":33,"link":597,"overload":4,"palsy":4,"phase":12,"revive":1,"shieldBreak":10,"splash":118,"substitute":3,"swap":3,"teleport":6},
|
||||
"snaps": "37ac48f3 092a4bc2 41b7e5d4 56d6fd20 79e6de1e 5c8059ed c19e7138 677e05fa cbd43f62 8f0f65b8 4d76189a 297c0633 3bc4d3c3 9ff783eb 79b3ec5e 5c6f5ce5 a8d3399b 8de60a18 1eaa3427 f2260143"
|
||||
"hooks": [1,33,6000,894,894,3465,8457,4295,12,15,104,100,124,25057,1653,12,13,0,1,78,0,2,0],
|
||||
"events": {"atk":1389,"deploy":20,"die":15,"dmg":7934,"engage":10,"fx":855,"heal":375,"skill":204,"spawn":25,"status":337},
|
||||
"fx": {"anchor":4,"aoe":2,"beam":24,"burst":2,"candle":6,"charge":7,"dash":12,"downed":1,"ember":1,"explode":1,"healAoe":34,"link":597,"overload":4,"palsy":2,"phase":12,"revive":1,"shieldBreak":11,"sleepGuard":1,"splash":124,"substitute":2,"swap":2,"teleport":4,"wake":1},
|
||||
"snaps": "37ac48f3 f657c2f6 e25b0f01 5ea69d76 c3a7469d 9558529b 0fd83c8e 2c035602 b69af21f c2a0eb54 b31f2ad7 8b64e08b bbbd8e09 0dca9aae ce7aae50 b0cd3d8c 35382dd2 d3b4e413 db5e9c68 41e7d434"
|
||||
},
|
||||
"hidden-boss_10-pair": {
|
||||
"about": "假想敌:管 pair pool 15200000: chess_char_5_19_b chess_char_4_01_b chess_char_5_14_b chess_char_5_17_b chess_char_5_15_b chess_char_5_20_b chess_char_5_21_b chess_char_5_22_b chess_char_5_23_b chess_char_4_02_b | chess_char_4_11_b chess_char_4_04_b chess_char_4_07_b chess_char_4_16_b chess_char_4_09_b chess_char_4_06_b chess_char_4_10_b chess_char_4_12_b chess_char_4_13_b chess_char_4_14_b token_10041_cathy_catsld token_10041_cathy_catsld",
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
"combat": "client",
|
||||
"boost": null,
|
||||
"setup": {"stageId":"act1autochess_m01","bossId":"boss_5","hiddenBossId":null,"factions":["ELEMENT","DOT","REFLECTION"]},
|
||||
"end": {"victory":false,"roundsPassed":8,"hiddenReached":false,"hiddenCleared":false,"reason":"defeat","teamLp":0,"bossPoolLeft":97187,"virtualMs":68100},
|
||||
"end": {"victory":false,"roundsPassed":8,"hiddenReached":false,"hiddenCleared":false,"reason":"defeat","teamLp":0,"bossPoolLeft":96711,"virtualMs":68100},
|
||||
"rng": {"setup":16,"shop":161,"waves":0,"draft":0,"bots":5205,"meta":43},
|
||||
"errors": {"engine":0,"logged":0,"sim":0,"dispatcher":0},
|
||||
"rounds": [
|
||||
@@ -83,7 +83,7 @@
|
||||
"title": {"id":"comment_2","name":"不朽盟约","picId":"comment_icon_2","text":"激活的盟约层数总和最高"},
|
||||
"trophies": 0,
|
||||
"reward": 100,
|
||||
"stats": {"activatedLayers":128,"bossDamage":102813,"dmgDealt":703977,"gold":78,"itemsEquipped":16,"kills":141,"leaks":0,"lpLost":0,"merges":0,"perfectRounds":8,"refreshes":18},
|
||||
"stats": {"activatedLayers":128,"bossDamage":103289,"dmgDealt":704453,"gold":78,"itemsEquipped":16,"kills":141,"leaks":0,"lpLost":0,"merges":0,"perfectRounds":8,"refreshes":18},
|
||||
"lineup": ["3_20_a@12,3[4_07_e_a+3_04_e_b]","2_14_a@12,4","2_05_a@12,6","3_10_a@11,3[2_03_e_a]","4_14_a@11,8[4_02_e_a+4_08_e_a]","1_06_a@10,3[1_05_e_b+5_02_e_a]","1_02_a@10,4[3_08_e_a+2_01_e_b]","4_11_a@10,8[4_04_e_a+1_01_e_a]"],
|
||||
"bonds": ["deputShip 2/40","emptyShip 1/12","kjeragShip 1/28","steadShip 0/26","swiftShip 1/18","victoriaShip 1/30"]
|
||||
}
|
||||
@@ -615,7 +615,7 @@
|
||||
"title": {"id":"comment_1","name":"卫戍之星","picId":"comment_icon_1","text":"对敌方领袖造成伤害最高(仅胜利时)"},
|
||||
"trophies": 4,
|
||||
"reward": 400,
|
||||
"stats": {"activatedLayers":192,"bossDamage":1134983,"dmgDealt":4217825,"gold":135,"itemsEquipped":19,"kills":324,"leaks":9,"lpLost":9,"merges":4,"perfectRounds":11,"refreshes":14},
|
||||
"stats": {"activatedLayers":192,"bossDamage":1134983,"dmgDealt":4217747,"gold":135,"itemsEquipped":19,"kills":324,"leaks":9,"lpLost":9,"merges":4,"perfectRounds":11,"refreshes":14},
|
||||
"lineup": ["6_08_a@12,8","1_17_b@11,7[3_04_e_a+4_08_e_b]","4_20_a@11,8[5_02_e_a+4_04_e_a]","4_10_a@10,5[1_02_e_b+4_10_e_a]","6_17_a@10,8","6_08_a@9,7[4_07_e_a+3_01_e_a]","4_02_a@9,8","1_19_b@9,9[2_04_e_a+1_05_e_b]"],
|
||||
"bonds": ["arcaneShip 2/30","kazimierzShip 1/56","kjeragShip 0/2","preciShip 2/106","sargonShip 0/10","steadShip 0/6","suntShip 1/0","swiftShip 0/11"]
|
||||
}
|
||||
@@ -1160,7 +1160,7 @@
|
||||
"title": {"id":"comment_5","name":"万事俱备","picId":"comment_icon_5","text":"装备配发数量最多"},
|
||||
"trophies": 2,
|
||||
"reward": 213,
|
||||
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":2811692,"gold":100,"itemsEquipped":12,"kills":132,"leaks":36,"lpLost":35,"merges":2,"perfectRounds":5,"refreshes":11},
|
||||
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":2812963,"gold":100,"itemsEquipped":12,"kills":132,"leaks":36,"lpLost":35,"merges":2,"perfectRounds":5,"refreshes":11},
|
||||
"lineup": [],
|
||||
"bonds": ["deputShip 0/40","egirShip 0/2","kazimierzShip 0/4","kjeragShip 0/81","raidShip 0/16","skillfulShip 0/50","soloShip 0/6","steadShip 0/40","suntShip 0/18","swiftShip 0/6","victoriaShip 0/56","yanShip 0/16"]
|
||||
},
|
||||
@@ -1385,7 +1385,7 @@
|
||||
"combat": "client",
|
||||
"boost": {"lp":400,"layers":300},
|
||||
"setup": {"stageId":"act2autochess_m04","bossId":"boss_5","hiddenBossId":"boss_9","factions":["FLY","ELEMENT","INVISIBLE"]},
|
||||
"end": {"victory":true,"roundsPassed":15,"hiddenReached":true,"hiddenCleared":true,"reason":"victory","teamLp":408,"bossPoolLeft":0,"virtualMs":123150},
|
||||
"end": {"victory":true,"roundsPassed":15,"hiddenReached":true,"hiddenCleared":true,"reason":"victory","teamLp":409,"bossPoolLeft":0,"virtualMs":123150},
|
||||
"rng": {"setup":25,"shop":681,"waves":0,"draft":61,"bots":22075,"meta":140},
|
||||
"errors": {"engine":0,"logged":0,"sim":0,"dispatcher":0},
|
||||
"rounds": [
|
||||
@@ -1461,12 +1461,12 @@
|
||||
"victory": true,
|
||||
"roundsPassed": 15,
|
||||
"eliminatedRound": null,
|
||||
"lp": 204,
|
||||
"lp": 205,
|
||||
"bandId": "band_sarkazb",
|
||||
"title": {"id":"comment_2","name":"不朽盟约","picId":"comment_icon_2","text":"激活的盟约层数总和最高"},
|
||||
"trophies": 8,
|
||||
"reward": 425,
|
||||
"stats": {"activatedLayers":2908,"bossDamage":4593567,"dmgDealt":16196818,"gold":176,"itemsEquipped":24,"kills":287,"leaks":0,"lpLost":0,"merges":6,"perfectRounds":13,"refreshes":31},
|
||||
"stats": {"activatedLayers":2908,"bossDamage":4535557,"dmgDealt":16042673,"gold":176,"itemsEquipped":24,"kills":287,"leaks":0,"lpLost":0,"merges":6,"perfectRounds":13,"refreshes":31},
|
||||
"lineup": ["3_16_b@12,8[4_02_e_b+5_01_e_a]","3_11_b@11,8[3_01_e_a+1_01_e_b]","3_20_a@10,3[5_02_e_a+3_07_e_a]","1_02_b@10,4[1_02_e_a+4_05_e_a]","5_06_a@10,8[4_04_e_a+3_04_e_b]","4_21_b@9,7","6_12_a@9,8[3_08_e_a+1_05_e_a]","5_10_a@9,9[2_01_e_a+4_06_e_a]"],
|
||||
"bonds": ["arcaneShip 0/314","deputShip 1/317","egirShip 0/300","emptyShip 1/306","indomShip 1/306","investShip 0/300","kazimierzShip 0/302","kjeragShip 1/345","lateranoShip 0/300","maniShip 0/300","miraShip 0/300","preciShip 1/340","raidShip 0/300","sargonShip 0/300","siracusaShip 0/300","skillfulShip 1/323","soloShip 0/306","steadShip 1/353","suntShip 1/312","swiftShip 0/302","victoriaShip 0/300","visiShip 1/306","yanShip 0/300"]
|
||||
},
|
||||
@@ -1480,7 +1480,7 @@
|
||||
"title": {"id":"comment_1","name":"卫戍之星","picId":"comment_icon_1","text":"对敌方领袖造成伤害最高(仅胜利时)"},
|
||||
"trophies": 8,
|
||||
"reward": 425,
|
||||
"stats": {"activatedLayers":2599,"bossDamage":9288137,"dmgDealt":29429364,"gold":160,"itemsEquipped":32,"kills":277,"leaks":1,"lpLost":0,"merges":5,"perfectRounds":12,"refreshes":36},
|
||||
"stats": {"activatedLayers":2599,"bossDamage":9346147,"dmgDealt":29241266,"gold":160,"itemsEquipped":32,"kills":277,"leaks":1,"lpLost":0,"merges":5,"perfectRounds":12,"refreshes":36},
|
||||
"lineup": ["3_16_a@12,8[3_03_e_b+4_04_e_b]","2_10_b@11,5[2_03_e_a+2_03_e_b]","1_06_b@11,8[3_02_e_a+4_09_e_b]","2_17_a@10,4[5_02_e_a+5_09_e_a]","5_06_a@10,8[3_09_e_b+3_09_e_b]","4_21_a@9,6[5_03_e_a+3_06_e_a]","5_02_a@9,8[3_06_e_b+2_03_e_b]","1_17_a@9,9[4_09_e_b+3_10_e_b]"],
|
||||
"bonds": ["arcaneShip 1/316","deputShip 1/316","egirShip 0/300","emptyShip 0/300","indomShip 1/306","investShip 0/300","kazimierzShip 0/300","kjeragShip 0/300","lateranoShip 0/300","maniShip 0/300","miraShip 0/300","preciShip 1/392","raidShip 0/300","sargonShip 0/300","siracusaShip 0/300","skillfulShip 1/306","soloShip 1/314","steadShip 1/345","suntShip 1/304","swiftShip 0/300","victoriaShip 0/316","visiShip 0/300","yanShip 0/300"]
|
||||
}
|
||||
|
||||
+86
-86
@@ -84,44 +84,44 @@
|
||||
"bossHpLeft": null,
|
||||
"rngDraws": 88,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {"p1":{"killed":29,"total":44,"perfect":false,"leaks":15,"leaksUncounted":0,"coins":8,"dmg":244258,"bossDmg":0,"heal":5475,"deaths":15,"layerGains":{}}},
|
||||
"players": {"p1":{"killed":29,"total":44,"perfect":false,"leaks":15,"leaksUncounted":0,"coins":8,"dmg":244940,"bossDmg":0,"heal":5867,"deaths":14,"layerGains":{}}},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_1_02_b",1,"uniequip_002_yak",0,0,3,2,7539,4874,0,22,1],
|
||||
["p1",2,"op","chess_char_1_20_a",1,null,2857.4,1,1,0,0,0,0,0,0],
|
||||
["p1",3,"op","chess_char_1_04_b",1,"uniequip_002_udflow",2356.31,1,4,1,4860,1419,0,7,1],
|
||||
["p1",3,"op","chess_char_1_04_b",1,"uniequip_002_udflow",2402.9,1,4,1,4860,1372,0,7,1],
|
||||
["p1",4,"op","chess_char_1_08_b",1,"uniequip_002_texas",0,0,7,1,10182,3473,0,1,3],
|
||||
["p1",5,"op","chess_char_1_18_a",1,null,0,0,60,2,3473,6928,350,7,2],
|
||||
["p1",6,"op","chess_char_1_19_a",1,null,0,0,57,0,7018,3853,0,10,1],
|
||||
["p1",7,"op","chess_char_1_17_a",1,null,0,0,5,0,0,1481,0,0,0],
|
||||
["p1",8,"op","chess_char_1_01_b",1,"uniequip_002_inside",0,0,8,5,59193,4079,0,62,3],
|
||||
["p1",9,"op","chess_char_1_03_b",1,"uniequip_002_leizi",0,0,62,4,28255,3617,0,14,1],
|
||||
["p1",10,"op","chess_char_1_06_b",1,"uniequip_002_vendla",0,0,61,6,24730,6539,5125,31,2],
|
||||
["p1",8,"op","chess_char_1_01_b",1,"uniequip_002_inside",0,0,8,5,59193,4121,0,62,3],
|
||||
["p1",9,"op","chess_char_1_03_b",1,"uniequip_002_leizi",634.91,1,62,4,28255,2982,0,14,1],
|
||||
["p1",10,"op","chess_char_1_06_b",1,"uniequip_002_vendla",0,0,61,6,25412,6889,5517,30,2],
|
||||
["p1",11,"op","chess_char_1_07_b",0,"uniequip_002_prove",0,0,59,5,35730,5955,0,27,0],
|
||||
["p1",12,"op","chess_char_1_09_b",1,"uniequip_002_caper",801.74,1,2,3,63277,2078,0,44,2]
|
||||
["p1",12,"op","chess_char_1_09_b",1,"uniequip_002_caper",608.68,1,2,3,63277,2271,0,44,2]
|
||||
],
|
||||
"enemies": {
|
||||
"enemy_1000_gopro_2": [1,1,0,0,2938],
|
||||
"enemy_10065_ftzlc": [1,1,0,0,6566],
|
||||
"enemy_10112_ymgds": [1,1,0,0,8640],
|
||||
"enemy_1019_jshoot": [9,3,5,13909,12884],
|
||||
"enemy_1019_jshoot": [9,3,5,13541,12884],
|
||||
"enemy_1040_bombd": [1,1,0,0,6912],
|
||||
"enemy_1043_zomsbr": [18,17,1,482,83466],
|
||||
"enemy_1116_liprr": [1,1,0,0,9504],
|
||||
"enemy_1168_dumage_2": [1,1,0,2185,11232],
|
||||
"enemy_1199_sfjin": [1,1,0,0,11232],
|
||||
"enemy_1200_msfjin": [1,0,1,0,18],
|
||||
"enemy_1234_dsubrl": [1,0,1,6225,12848],
|
||||
"enemy_1234_dsubrl": [1,0,1,6643,13784],
|
||||
"enemy_1288_duskls_2": [1,0,1,0,10368],
|
||||
"enemy_1299_ymkilr": [3,1,2,3672,14688],
|
||||
"enemy_1381_winman_2": [1,1,0,0,13478],
|
||||
"enemy_1501_demonk": [1,0,0,6100,12225],
|
||||
"enemy_2005_axetro": [1,0,0,8433,23361],
|
||||
"enemy_9011_acrefr": [1,0,0,0,3898]
|
||||
"enemy_1501_demonk": [1,0,0,5700,12225],
|
||||
"enemy_2005_axetro": [1,0,0,8686,23361],
|
||||
"enemy_9011_acrefr": [1,0,0,0,3643]
|
||||
},
|
||||
"hooks": [1,62,3300,365,365,452,493,3061,44,55,16,18,48,7405,32,11,44,11,1,45,0,0,0],
|
||||
"events": {"atk":384,"bounty":4,"deploy":18,"die":44,"dmg":493,"engage":10,"fx":79,"heal":32,"leak":11,"skill":37,"spawn":56,"status":64},
|
||||
"fx": {"aoe":5,"counter":9,"crit":24,"displace":10,"dp":3,"ember":1,"pulse":22,"revive":1,"sp":1,"summon":1,"taunt":2},
|
||||
"snaps": "ccf62e58 0169998c b859efed 32758178 83e51a60 5ea49804 e568e9f3 ccd82ab0 6deb6218 87da45df 9c7b415f"
|
||||
"hooks": [1,62,3300,362,362,457,501,3066,43,54,16,18,48,7468,32,11,44,11,1,44,0,0,0],
|
||||
"events": {"atk":381,"bounty":4,"deploy":18,"die":43,"dmg":501,"engage":10,"fx":85,"heal":37,"leak":11,"skill":37,"spawn":56,"status":64},
|
||||
"fx": {"aoe":5,"counter":15,"crit":24,"displace":10,"dp":3,"ember":1,"pulse":22,"revive":1,"sp":1,"summon":1,"taunt":2},
|
||||
"snaps": "ccf62e58 0169998c b859efed 32758178 83e51a60 cd5d1ee2 3b71618a 43aef881 7ba1a8fd d818e346 2d42e3bb"
|
||||
},
|
||||
"roster-003": {
|
||||
"about": "pass 0 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 token_10000_silent_healrb",
|
||||
@@ -240,8 +240,8 @@
|
||||
"enemy_1504_cqbw": [1,0,1,652,630],
|
||||
"enemy_2009_csaudc": [1,0,1,0,490]
|
||||
},
|
||||
"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},
|
||||
"hooks": [1,57,3300,435,435,1418,1439,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":1372,"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"
|
||||
},
|
||||
@@ -263,16 +263,16 @@
|
||||
"bossHpLeft": null,
|
||||
"rngDraws": 334,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {"p1":{"killed":83,"total":84,"perfect":false,"leaks":1,"leaksUncounted":0,"coins":10,"dmg":306697,"bossDmg":0,"heal":37410,"deaths":0,"layerGains":{}}},
|
||||
"players": {"p1":{"killed":83,"total":84,"perfect":false,"leaks":1,"leaksUncounted":0,"coins":10,"dmg":306697,"bossDmg":0,"heal":36659,"deaths":0,"layerGains":{}}},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_2_07_b",1,"uniequip_002_ghost",2664.2,1,2,0,0,1707,1318,0,0],
|
||||
["p1",2,"op","chess_char_2_08_b",1,"uniequip_002_bubble",3373,1,4,0,49,1818,0,0,1],
|
||||
["p1",1,"op","chess_char_2_07_b",1,"uniequip_002_ghost",2664.2,1,2,0,0,1305,1184,0,0],
|
||||
["p1",2,"op","chess_char_2_08_b",1,"uniequip_002_bubble",3373,1,4,0,73,1469,0,0,1],
|
||||
["p1",3,"op","chess_char_2_09_b",1,"uniequip_002_humus",2133,1,6,28,84020,0,0,59,2],
|
||||
["p1",4,"op","chess_char_2_11_b",1,"uniequip_002_kazema",2214,1,8,12,91244,15658,0,92,3],
|
||||
["p1",4,"op","chess_char_2_11_b",1,"uniequip_002_kazema",2214,1,8,12,91220,15658,0,92,3],
|
||||
["p1",5,"op","chess_char_2_12_b",1,"uniequip_002_gravel",1452,1,10,2,7180,9417,0,129,1],
|
||||
["p1",6,"op","chess_char_2_19_a",1,null,1021.2,1,11,1,14957,1433,314,26,3],
|
||||
["p1",7,"op","chess_char_2_01_b",1,"uniequip_002_excu",2146,1,12,20,36079,4363,0,22,1],
|
||||
["p1",8,"op","chess_char_2_02_b",1,"uniequip_002_silent",1614,1,1,0,0,0,9366,28,6],
|
||||
["p1",8,"op","chess_char_2_02_b",1,"uniequip_002_silent",1614,1,1,0,0,0,8747,26,6],
|
||||
["p1",9,"op","chess_char_2_04_b",1,"uniequip_002_grabds",1270,1,3,10,38233,2115,0,53,3],
|
||||
["p1",10,"op","chess_char_2_05_b",1,"uniequip_002_harold",1971.2,1,5,0,0,0,11081,40,2],
|
||||
["p1",11,"op","chess_char_2_06_b",0,"uniequip_002_papyrs",1639,1,7,0,0,0,12196,27,13],
|
||||
@@ -280,7 +280,7 @@
|
||||
["p1",13,"token","token_10000_silent_healrb",null,null,1000,1,104,0,0,0,3137,30,null]
|
||||
],
|
||||
"enemies": {
|
||||
"enemy_10027_vtsk": [1,0,0,10552,23138],
|
||||
"enemy_10027_vtsk": [1,0,0,9831,23138],
|
||||
"enemy_1006_shield_2": [1,1,0,0,8000],
|
||||
"enemy_10122_uacann_2": [1,1,0,3476,8000],
|
||||
"enemy_1042_frostd": [1,1,0,0,5200],
|
||||
@@ -292,13 +292,13 @@
|
||||
"enemy_1299_ymkilr_2": [1,1,0,1178,8800],
|
||||
"enemy_1328_cbjedi": [6,6,0,8950,48000],
|
||||
"enemy_1402_tgshd_2": [1,1,0,20,10400],
|
||||
"enemy_1509_mousek": [1,1,0,7192,17600],
|
||||
"enemy_1509_mousek": [1,1,0,7162,17600],
|
||||
"enemy_2010_csdcr": [1,1,0,1986,9600]
|
||||
},
|
||||
"hooks": [1,103,4200,714,714,1650,1643,1083,83,89,37,36,0,29028,143,53,84,0,1,83,0,0,0],
|
||||
"events": {"atk":926,"bounty":5,"deploy":19,"die":89,"dmg":1603,"engage":7,"fx":66,"heal":134,"skill":73,"spawn":97,"status":433},
|
||||
"fx": {"counter":2,"explode":3,"expose":9,"overload":2,"phase":1,"shield":8,"shieldBreak":16,"sleep":7,"summon":6,"telegraph":6,"zone":6},
|
||||
"snaps": "84edc036 a46838b0 1d9bc714 1b570575 aab0920b 4bc6df97 dd7f1064 918ab11b 31267425 a4452600 f9a6edeb 9a33bdd8 c9a35f1c 7d3f9999"
|
||||
"hooks": [1,103,4200,712,712,1778,1771,1006,83,89,37,36,0,29028,143,53,84,0,1,83,0,0,0],
|
||||
"events": {"atk":924,"bounty":5,"deploy":19,"die":89,"dmg":1731,"engage":7,"fx":67,"heal":132,"skill":73,"spawn":97,"status":433},
|
||||
"fx": {"counter":3,"explode":3,"expose":9,"overload":2,"phase":1,"shield":8,"shieldBreak":16,"sleep":7,"summon":6,"telegraph":6,"zone":6},
|
||||
"snaps": "a3fef71a 5b6f2bc9 5ab142c1 b7176554 ec4a18ae a8c6c736 a4c4a9f5 942f8b3e d1bf1d78 7f1d627f 7338a7c7 d43d8077 a8633ecb 52300afa"
|
||||
},
|
||||
"roster-006": {
|
||||
"about": "pass 0 band 3: chess_char_2_17_b chess_char_2_18_b chess_char_3_06_a chess_char_2_13_b chess_char_2_16_b chess_char_3_02_a chess_char_3_03_a chess_char_3_04_a chess_char_3_05_a chess_char_2_14_b chess_char_2_19_b chess_char_3_01_a",
|
||||
@@ -524,8 +524,8 @@
|
||||
"enemy_2025_syufo": [13,3,7,34695,151025]
|
||||
},
|
||||
"hooks": [1,131,5100,586,586,1158,1255,394,69,124,21,24,0,10104,74,48,88,31,1,75,14,12,0],
|
||||
"events": {"atk":679,"bounty":4,"deploy":43,"die":93,"dmg":1199,"engage":12,"fx":192,"heal":393,"layer":14,"leak":31,"skill":49,"spawn":120,"status":125},
|
||||
"fx": {"aoe":1,"blink":4,"buff":1,"burst":12,"coin":23,"displace":31,"explode":26,"garrison":9,"layer":5,"pull":31,"revive":6,"shield":1,"shieldBreak":1,"stone":1,"strike":9,"summon":21,"telegraph":1,"volley":9},
|
||||
"events": {"atk":679,"bounty":4,"deploy":43,"die":93,"dmg":1199,"engage":12,"fx":212,"heal":393,"layer":14,"leak":31,"skill":49,"spawn":120,"status":125},
|
||||
"fx": {"aoe":21,"blink":4,"buff":1,"burst":12,"coin":23,"displace":31,"explode":26,"garrison":9,"layer":5,"pull":31,"revive":6,"shield":1,"shieldBreak":1,"stone":1,"strike":9,"summon":21,"telegraph":1,"volley":9},
|
||||
"snaps": "d491f937 8ffbd7b3 9e67e1b5 7e887872 27c243c0 3f150bd7 8e79d798 8c8aa383 1ace5379 888f0b4b 72fc5e5e b0e185b5 44f8935f fe76c659 0db9aa25 e37eea06 638b6604"
|
||||
},
|
||||
"roster-009": {
|
||||
@@ -608,10 +608,10 @@
|
||||
"rngDraws": 78,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {
|
||||
"p1": {"killed":34,"total":102,"perfect":false,"leaks":68,"leaksUncounted":0,"coins":6,"dmg":370675,"bossDmg":0,"heal":1763,"deaths":21,"layerGains":{"preciShip":8}}
|
||||
"p1": {"killed":34,"total":102,"perfect":false,"leaks":68,"leaksUncounted":0,"coins":6,"dmg":374265,"bossDmg":0,"heal":1763,"deaths":21,"layerGains":{"preciShip":8}}
|
||||
},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_4_17_a",1,null,0,0,5,0,1650,2849,0,12,0],
|
||||
["p1",1,"op","chess_char_4_17_a",1,null,0,0,5,0,5240,2849,0,12,0],
|
||||
["p1",2,"op","chess_char_4_18_a",1,null,0,0,6,0,1816,4317,1450,3,3],
|
||||
["p1",3,"op","chess_char_4_11_a",1,null,2144,1,128,0,484,2969,0,1,1],
|
||||
["p1",4,"op","chess_char_4_19_a",2,null,0,0,95,0,12345,3120,0,20,1],
|
||||
@@ -636,7 +636,7 @@
|
||||
"enemy_1005_yokai_3": [6,0,5,18350,83393],
|
||||
"enemy_10083_hlbird": [1,1,0,0,6450],
|
||||
"enemy_10144_xdelk_2": [1,0,1,2974,31667],
|
||||
"enemy_1050_lslime": [1,0,1,9009,21335],
|
||||
"enemy_1050_lslime": [1,0,1,9009,24925],
|
||||
"enemy_1158_divman": [1,1,0,305,14189],
|
||||
"enemy_1174_duholy_2": [1,0,1,1192,4347],
|
||||
"enemy_1204_msfhu_2": [1,1,0,0,6],
|
||||
@@ -647,10 +647,10 @@
|
||||
"enemy_1516_jakill": [1,0,1,81,0],
|
||||
"enemy_2034_sythef_2": [1,0,1,0,0]
|
||||
},
|
||||
"hooks": [1,130,5100,423,423,1014,982,222,55,117,21,22,0,7786,429,11,102,62,1,170,2,0,23],
|
||||
"events": {"atk":520,"bounty":3,"deploy":25,"die":55,"dmg":898,"engage":12,"fx":160,"heal":5,"layer":2,"leak":62,"skill":44,"spawn":119,"status":287},
|
||||
"fx": {"block":9,"catShield":2,"charge":1,"dilemma":1,"dodge":23,"explode":16,"explosion":2,"featherArrow":1,"flame":1,"frostNova":4,"garrison":2,"garrisonGrant":1,"overclock":1,"phase":1,"pull":1,"riposte":1,"rockslide":3,"shieldBreak":5,"slippery":1,"summon":11,"swordRain":48,"swordStorm":5,"telegraph":2,"thorns":6,"tornado":1,"tornadoPulse":5,"undying":6},
|
||||
"snaps": "57fe2e2f 9740eab7 bc769df4 4b11e270 22996d81 de0a7802 8a9b54fe 11b5d7b3 27f8d1f7 407381fb 454bf8fe fb11d7df adcdf5d5 fac269bf c684cb06 d99688cd 0cfb92e2"
|
||||
"hooks": [1,130,5100,423,423,1029,997,222,55,117,21,22,0,7786,429,11,102,62,1,170,2,0,23],
|
||||
"events": {"atk":520,"bounty":3,"deploy":25,"die":55,"dmg":913,"engage":12,"fx":175,"heal":5,"layer":2,"leak":62,"skill":44,"spawn":119,"status":287},
|
||||
"fx": {"block":9,"catShield":2,"charge":1,"dilemma":1,"dodge":23,"explode":16,"explosion":2,"featherArrow":1,"flame":1,"frostNova":4,"garrison":2,"garrisonGrant":1,"overclock":1,"phase":1,"pull":1,"riposte":1,"rockslide":3,"shieldBreak":5,"slippery":1,"summon":11,"swordRain":48,"swordStorm":5,"telegraph":2,"thorns":21,"tornado":1,"tornadoPulse":5,"undying":6},
|
||||
"snaps": "57fe2e2f 9740eab7 bc769df4 4b11e270 22996d81 21c4f85b b11a1d11 d9930d54 32c104ad 48940391 2875c690 fa4e30b9 e3c2ed67 439d1b5d 98710bbc 2b3b8707 201d4164"
|
||||
},
|
||||
"roster-011": {
|
||||
"about": "pass 0 band 5: chess_char_4_23_a chess_char_4_01_b chess_char_4_22_a chess_char_4_04_b chess_char_4_07_b chess_char_4_09_b chess_char_4_21_a chess_char_4_24_a chess_char_4_25_a chess_char_4_26_a chess_char_4_02_b chess_char_4_06_b",
|
||||
@@ -721,8 +721,8 @@
|
||||
"round": 10,
|
||||
"seed": 1517795683,
|
||||
"waveId": "act1autochess_h03",
|
||||
"time": 162.6,
|
||||
"ticks": 4878,
|
||||
"time": 161.57,
|
||||
"ticks": 4847,
|
||||
"reason": "cleared",
|
||||
"killed": 99,
|
||||
"total": 100,
|
||||
@@ -731,21 +731,21 @@
|
||||
"rngDraws": 187,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {
|
||||
"p1": {"killed":99,"total":100,"perfect":false,"leaks":1,"leaksUncounted":0,"coins":10,"dmg":983916,"bossDmg":0,"heal":22157,"deaths":7,"layerGains":{"preciShip":8}}
|
||||
"p1": {"killed":99,"total":100,"perfect":false,"leaks":1,"leaksUncounted":0,"coins":10,"dmg":988651,"bossDmg":0,"heal":21802,"deaths":7,"layerGains":{"preciShip":8}}
|
||||
},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_4_17_b",1,"uniequip_002_hsguma",3046.73,1,7,0,184,466,0,20,0],
|
||||
["p1",2,"op","chess_char_4_18_b",1,"uniequip_002_mudrok",6104,1,9,4,57534,2092,2092,32,7],
|
||||
["p1",1,"op","chess_char_4_17_b",1,"uniequip_002_hsguma",3046.73,1,7,0,237,466,0,20,0],
|
||||
["p1",2,"op","chess_char_4_18_b",1,"uniequip_002_mudrok",6104,1,9,5,65239,2337,2337,37,8],
|
||||
["p1",3,"op","chess_char_4_11_b",1,"uniequip_002_cathy",2644,1,124,0,2731,3521,0,3,1],
|
||||
["p1",4,"op","chess_char_4_19_b",2,"uniequip_002_flamtl",0,0,104,4,45091,4236,0,45,3],
|
||||
["p1",5,"op","chess_char_4_22_b",2,"uniequip_002_svrash",2169,1,122,10,105064,5538,0,27,3],
|
||||
["p1",6,"op","chess_char_4_16_b",2,"uniequip_002_texas2",1619,1,113,3,4767,5745,362,24,3],
|
||||
["p1",4,"op","chess_char_4_19_b",2,"uniequip_002_flamtl",0,0,104,5,40856,4236,0,40,3],
|
||||
["p1",5,"op","chess_char_4_22_b",2,"uniequip_002_svrash",2219,1,122,9,108386,5488,0,27,3],
|
||||
["p1",6,"op","chess_char_4_16_b",2,"uniequip_002_texas2",1619,1,113,4,16046,5745,362,23,5],
|
||||
["p1",7,"op","chess_char_4_10_b",1,"uniequip_002_aroma",1664,1,4,0,0,0,0,0,0],
|
||||
["p1",8,"op","chess_char_4_12_b",2,"uniequip_002_glady",2232,1,5,2,6911,557,557,14,2],
|
||||
["p1",9,"op","chess_char_4_13_b",1,"uniequip_002_gnosis",1989,1,11,20,187170,2441,0,92,38],
|
||||
["p1",10,"op","chess_char_4_14_b",1,"uniequip_002_lionhd",1576,1,13,44,488221,7756,0,57,23],
|
||||
["p1",11,"op","chess_char_4_20_b",2,"uniequip_002_fartth",0,0,6,12,86244,1419,0,28,5],
|
||||
["p1",12,"op","chess_char_4_21_b",1,"uniequip_002_plosis",1534,1,14,0,0,9049,19146,96,2],
|
||||
["p1",8,"op","chess_char_4_12_b",2,"uniequip_002_glady",2232,1,5,1,5724,557,557,13,2],
|
||||
["p1",9,"op","chess_char_4_13_b",1,"uniequip_002_gnosis",1989,1,11,20,179263,2491,0,91,36],
|
||||
["p1",10,"op","chess_char_4_14_b",1,"uniequip_002_lionhd",1526,1,13,43,487394,7656,0,58,23],
|
||||
["p1",11,"op","chess_char_4_20_b",2,"uniequip_002_fartth",0,0,6,12,82773,1419,0,27,5],
|
||||
["p1",12,"op","chess_char_4_21_b",1,"uniequip_002_plosis",1484,1,14,0,0,8599,18546,100,2],
|
||||
["p1",13,"token","token_10041_cathy_catsld",null,null,100,1,17,0,0,0,0,0,null],
|
||||
["p1",14,"token","token_10041_cathy_catsld",null,null,100,1,16,0,0,0,0,0,null],
|
||||
["-","~1","device","trap_1105_accrate",null,null,100,0,1,0,0,0,0,0,null],
|
||||
@@ -761,19 +761,19 @@
|
||||
"enemy_1183_mlasrt": [1,1,0,988,7488],
|
||||
"enemy_1207_sfji_2": [1,1,0,0,16128],
|
||||
"enemy_1208_msfji_2": [4,4,0,0,120],
|
||||
"enemy_1267_nhpbr": [45,45,0,12545,233280],
|
||||
"enemy_1267_nhpbr_2": [24,24,0,8150,152064],
|
||||
"enemy_1267_nhpbr": [45,45,0,12777,233280],
|
||||
"enemy_1267_nhpbr_2": [24,24,0,7400,152064],
|
||||
"enemy_1270_nhstlk": [1,1,0,0,13824],
|
||||
"enemy_1270_nhstlk_2": [15,15,0,6817,276480],
|
||||
"enemy_1270_nhstlk_2": [15,15,0,7030,276480],
|
||||
"enemy_1325_cbgpro_2": [1,1,0,0,5299],
|
||||
"enemy_1425_lrcmra_2": [1,1,0,718,28800],
|
||||
"enemy_1525_blkswb": [1,0,1,11702,37587],
|
||||
"enemy_1525_blkswb": [1,0,1,11702,42321],
|
||||
"enemy_2050_smsha": [1,1,0,1902,46080]
|
||||
},
|
||||
"hooks": [1,122,4878,469,469,1415,1416,521,107,110,87,86,0,15601,1813,20,100,1,1,122,1,0,1],
|
||||
"events": {"atk":626,"bounty":5,"deploy":19,"die":109,"dmg":1408,"engage":10,"fx":238,"heal":213,"layer":1,"leak":1,"skill":175,"spawn":117,"status":929},
|
||||
"fx": {"beam":6,"blink":2,"displace":4,"dodge":1,"explode":4,"explosion":23,"featherArrow":5,"flame":3,"frostNova":38,"garrison":1,"garrisonGrant":1,"healField":2,"overclock":1,"palsy":1,"pull":2,"revive":4,"riposte":1,"rockslide":7,"shieldBreak":8,"slash":23,"summon":1,"swordRain":9,"swordStorm":3,"telegraph":4,"tornado":2,"tornadoPulse":10,"truesilver":3,"zone":69},
|
||||
"snaps": "a9c24b01 43e8c4cb 9f57bc24 f59bb440 6678caa3 a8a8f019 00aa512d 0d1483f9 3218befc 941b711a 42e275ff 71560683 48d17a97 d73abc3a cd6e4828 23a7c2fb ed427a58"
|
||||
"hooks": [1,122,4847,476,476,1436,1435,526,107,110,88,87,0,16368,1779,26,100,1,1,121,1,0,3],
|
||||
"events": {"atk":634,"bounty":5,"deploy":19,"die":109,"dmg":1425,"engage":10,"fx":269,"heal":217,"layer":1,"leak":1,"skill":177,"spawn":117,"status":920},
|
||||
"fx": {"beam":6,"blink":2,"displace":4,"dodge":3,"explode":5,"explosion":23,"featherArrow":5,"flame":3,"frostNova":36,"garrison":1,"garrisonGrant":1,"healField":2,"overclock":1,"palsy":1,"pull":2,"revive":4,"riposte":3,"rockslide":8,"shieldBreak":10,"slash":24,"summon":1,"swordRain":29,"swordStorm":5,"telegraph":3,"thorns":3,"tornado":2,"tornadoPulse":10,"truesilver":3,"zone":69},
|
||||
"snaps": "a9c24b01 43e8c4cb 9f57bc24 f59bb440 6678caa3 a8a8f019 00aa512d 0d1483f9 2a3527a2 03e0de1a 8e417627 3f822e54 df66a000 eac29e3c 8acf1281 0f15b00b 8758da2f"
|
||||
},
|
||||
"roster-013": {
|
||||
"about": "pass 0 band 5: chess_char_4_23_b chess_char_5_08_a chess_char_5_01_a chess_char_5_05_a chess_char_5_06_a chess_char_5_07_a chess_char_4_24_b chess_char_4_25_b chess_char_4_26_b chess_char_5_02_a chess_char_5_03_a chess_char_5_10_a",
|
||||
@@ -1020,10 +1020,10 @@
|
||||
"rngDraws": 571,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {
|
||||
"p1": {"killed":81,"total":126,"perfect":false,"leaks":45,"leaksUncounted":0,"coins":6,"dmg":3939977,"bossDmg":0,"heal":90944,"deaths":6,"layerGains":{"preciShip":4}}
|
||||
"p1": {"killed":81,"total":126,"perfect":false,"leaks":45,"leaksUncounted":0,"coins":6,"dmg":3940178,"bossDmg":0,"heal":90944,"deaths":6,"layerGains":{"preciShip":4}}
|
||||
},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_5_19_b",2,"uniequip_002_mlynar",699.59,1,112,13,452146,8026,912,86,4],
|
||||
["p1",1,"op","chess_char_5_19_b",2,"uniequip_002_mlynar",699.59,1,112,13,452346,8026,912,86,4],
|
||||
["p1",2,"op","chess_char_6_03_a",2,null,2433,1,108,0,89227,20851,8651,68,2],
|
||||
["p1",3,"op","chess_char_6_06_a",2,null,2223,1,6,9,453929,27394,1598,112,3],
|
||||
["p1",4,"op","chess_char_5_17_b",1,"uniequip_002_f12yin",2738,1,124,3,128622,31811,12917,287,2],
|
||||
@@ -1052,16 +1052,16 @@
|
||||
"enemy_1165_duhond": [1,1,0,127,17337],
|
||||
"enemy_1196_msfyin_2": [1,1,0,0,3],
|
||||
"enemy_1209_sfden_2": [1,0,1,896,53527],
|
||||
"enemy_1273_stmgun_2": [1,0,1,18044,12298],
|
||||
"enemy_1273_stmgun_2": [1,0,1,18044,12498],
|
||||
"enemy_1355_mrfly": [1,1,0,0,37150],
|
||||
"enemy_1433_dsbasi_2": [1,1,0,0,35293],
|
||||
"enemy_2001_duckmi_2": [1,0,1,0,21574],
|
||||
"enemy_9006_actoxi": [1,0,1,0,2453]
|
||||
},
|
||||
"hooks": [1,149,6900,1051,1115,7953,8194,74598,87,132,43,40,23,40522,1066,52,126,41,1,101,2,9,7],
|
||||
"events": {"atk":2422,"bounty":3,"deploy":23,"die":91,"dmg":8114,"engage":10,"fx":558,"heal":126,"layer":2,"leak":41,"skill":83,"spawn":143,"status":2555},
|
||||
"hooks": [1,149,6900,1051,1115,7954,8195,74598,87,132,43,40,23,40522,1066,52,126,41,1,101,2,9,7],
|
||||
"events": {"atk":2422,"bounty":3,"deploy":23,"die":91,"dmg":8115,"engage":10,"fx":558,"heal":126,"layer":2,"leak":41,"skill":83,"spawn":143,"status":2555},
|
||||
"fx": {"aoe":8,"bombard":23,"bombardShell":23,"burst":9,"crit":50,"dodge":7,"explode":20,"firewall":2,"garrison":2,"iceSpike":90,"lightning":151,"lock":23,"lure":3,"revive":1,"snow":80,"soul":1,"sp":3,"storm":5,"talent":2,"telegraph":7,"tide":4,"wanted":39,"weightless":5},
|
||||
"snaps": "76864815 62849bad 979bf882 6b70811d 77471bf1 8e66ebd8 02666633 c1dc150e 145550a5 6080947f aa2ba72c 6ee4266d 365ca43c 78917e6c ffef2326 a4eecc36 ac467f84 e9871e9c 94f12fea 35034509 b447ed16 846d4776 56ec1765"
|
||||
"snaps": "76864815 62849bad 979bf882 6b70811d 77471bf1 8e66ebd8 02666633 f77e1d7d 931a56ba d16149b4 8670841f b814bcee f69383b3 d35a75e7 68f2cebd d9cc2455 b9c02ebf af397cdf 224d9171 3fa68a76 2911d3e5 dcd8bbc5 540c0eaa"
|
||||
},
|
||||
"roster-017": {
|
||||
"about": "pass 0 band 6: chess_char_6_15_a chess_char_6_19_a chess_char_6_07_a chess_char_6_17_a chess_char_6_08_a chess_char_6_09_a chess_char_6_11_a chess_char_6_12_a chess_char_6_13_a chess_char_6_14_a chess_char_6_16_a chess_char_6_18_a",
|
||||
@@ -1521,19 +1521,19 @@
|
||||
"bossHpLeft": null,
|
||||
"rngDraws": 11,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {"p1":{"killed":167,"total":191,"perfect":false,"leaks":24,"leaksUncounted":0,"coins":6,"dmg":194675,"bossDmg":0,"heal":20738,"deaths":2,"layerGains":{}}},
|
||||
"players": {"p1":{"killed":167,"total":191,"perfect":false,"leaks":24,"leaksUncounted":0,"coins":6,"dmg":194675,"bossDmg":0,"heal":20517,"deaths":2,"layerGains":{}}},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_2_07_b",0,"none",0,0,3,45,68672,6586,3921,58,2],
|
||||
["p1",2,"op","chess_char_2_08_b",0,"none",3193,1,1,0,0,0,0,0,0],
|
||||
["p1",3,"op","chess_char_2_09_b",0,"none",0,0,4,1,1,2079,46,1,0],
|
||||
["p1",4,"op","chess_char_2_11_b",0,"none",1992.6,1,7,13,4490,2214,0,31,10],
|
||||
["p1",5,"op","chess_char_2_12_b",0,"none",1352,1,10,19,23053,2194,0,61,1],
|
||||
["p1",4,"op","chess_char_2_11_b",0,"none",1992.6,1,7,9,4486,1993,0,27,9],
|
||||
["p1",5,"op","chess_char_2_12_b",0,"none",1352,1,10,25,23059,2194,0,61,1],
|
||||
["p1",6,"op","chess_char_2_19_a",0,null,1021.2,1,5,50,33036,0,0,73,10],
|
||||
["p1",7,"op","chess_char_2_01_b",0,"none",2146,1,8,15,3240,0,0,19,2],
|
||||
["p1",7,"op","chess_char_2_01_b",0,"none",2146,1,8,13,3238,0,0,19,2],
|
||||
["p1",8,"op","chess_char_2_02_b",0,"none",2624.8,1,6,0,0,400,1289,9,1],
|
||||
["p1",9,"op","chess_char_2_04_b",0,"none",1180,1,9,23,55082,889,0,65,32],
|
||||
["p1",10,"op","chess_char_2_05_b",0,"none",1873.2,1,11,0,0,6919,3700,46,3],
|
||||
["p1",11,"op","chess_char_2_06_b",1,"none",1639,1,12,0,0,4376,11782,61,4],
|
||||
["p1",11,"op","chess_char_2_06_b",1,"none",1639,1,12,0,0,4376,11560,61,4],
|
||||
["p1",12,"op","chess_char_2_10_b",0,"none",1356,1,2,1,7101,0,0,77,3]
|
||||
],
|
||||
"enemies": {
|
||||
@@ -1552,10 +1552,10 @@
|
||||
"enemy_1381_winman_2": [1,1,0,33,7488],
|
||||
"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":78,"heal":151,"leak":21,"skill":133,"spawn":203,"status":529},
|
||||
"hooks": [1,203,4200,752,752,1080,1146,2414,169,190,67,64,0,13908,1032,48,191,21,1,177,0,0,0],
|
||||
"events": {"atk":961,"bounty":3,"deploy":12,"die":169,"dmg":1099,"engage":8,"fx":78,"heal":151,"leak":21,"skill":131,"spawn":203,"status":531},
|
||||
"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"
|
||||
"snaps": "3528dfb7 48905850 b9883203 0254972f 68bbe7b1 21b5d4c5 99820c60 e553a893 cf5cc1ce 5b1d1c6a bea6d936 32e95e04 058b1d27 6bf58b14"
|
||||
},
|
||||
"roster-025": {
|
||||
"about": "pass 1 band 3: chess_char_2_17_b chess_char_2_18_b chess_char_3_06_a chess_char_2_13_b chess_char_2_16_b chess_char_3_02_a chess_char_3_03_a chess_char_3_04_a chess_char_3_05_a chess_char_2_14_b chess_char_2_19_b chess_char_3_01_a",
|
||||
@@ -2032,7 +2032,7 @@
|
||||
"leaks": 132,
|
||||
"leaksUncounted": 0,
|
||||
"coins": 2,
|
||||
"dmg": 346977,
|
||||
"dmg": 349368,
|
||||
"bossDmg": 0,
|
||||
"heal": 42114,
|
||||
"deaths": 24,
|
||||
@@ -2041,8 +2041,8 @@
|
||||
},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_5_11_a",0,null,3628.8,1,198,2,15002,7551,4312,30,4],
|
||||
["p1",2,"op","chess_char_5_19_a",0,null,2167.52,1,196,3,36237,18040,49,14,3],
|
||||
["p1",3,"op","chess_char_5_13_a",0,null,0,0,193,5,70464,16349,83,31,1],
|
||||
["p1",2,"op","chess_char_5_19_a",0,null,2167.52,1,196,3,38727,18040,49,14,3],
|
||||
["p1",3,"op","chess_char_5_13_a",0,null,0,0,193,5,70364,16349,83,31,1],
|
||||
["p1",4,"op","chess_char_5_14_a",0,null,1546.99,1,197,1,6713,5581,1527,20,3],
|
||||
["p1",5,"op","chess_char_5_06_b",0,"uniequip_003_etlchi",0,0,179,14,123248,17506,7085,33,8],
|
||||
["p1",6,"op","chess_char_5_17_a",0,null,89.06,1,195,0,5573,17040,199,14,2],
|
||||
@@ -2065,14 +2065,14 @@
|
||||
"enemy_1196_msfyin": [1,1,0,0,2],
|
||||
"enemy_1252_lysytb_2": [1,0,1,307,9631],
|
||||
"enemy_1364_spnaxe_2": [1,0,1,2528,4741],
|
||||
"enemy_1404_msnip": [36,4,32,77857,127526],
|
||||
"enemy_1404_msnip": [36,4,32,77857,129916],
|
||||
"enemy_1516_jakill": [1,0,1,5154,1320],
|
||||
"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":119,"heal":451,"layer":7,"leak":132,"skill":135,"spawn":182,"status":264},
|
||||
"hooks": [1,198,6664,961,961,3430,3458,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":3416,"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"
|
||||
"snaps": "8b9c3026 e0f96062 a49bbfa8 29d89b05 0acdd66d bf39de85 9e043da7 0a498624 5c13efec 75baddb9 67cc60f9 f89c8ba6 accd5980 82e3a003 3f66378b 9ba9488f cb51d386 8814422f b9132254 1419b8c7 784dfe12 10f61101 8fbaffd9"
|
||||
},
|
||||
"roster-034": {
|
||||
"about": "pass 1 band 6: chess_char_5_08_b chess_char_5_11_b chess_char_5_19_b chess_char_5_13_b chess_char_5_14_b chess_char_5_07_b chess_char_5_17_b chess_char_5_10_b chess_char_5_12_b chess_char_5_15_b chess_char_5_20_b chess_char_5_21_b",
|
||||
@@ -2684,18 +2684,18 @@
|
||||
"bossHpLeft": null,
|
||||
"rngDraws": 102,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {"p1":{"killed":97,"total":119,"perfect":false,"leaks":22,"leaksUncounted":0,"coins":8,"dmg":3196440,"bossDmg":0,"heal":29602,"deaths":18,"layerGains":{}}},
|
||||
"players": {"p1":{"killed":97,"total":119,"perfect":false,"leaks":22,"leaksUncounted":0,"coins":8,"dmg":3196490,"bossDmg":0,"heal":29602,"deaths":18,"layerGains":{}}},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_5_19_a",1,null,3241,1,167,5,41218,11497,895,29,3],
|
||||
["p1",1,"op","chess_char_5_19_a",1,null,3241,1,167,5,42811,11497,895,29,3],
|
||||
["p1",2,"op","chess_char_5_11_b",2,"none",4564.8,1,169,4,21064,21466,23687,40,3],
|
||||
["p1",3,"op","chess_char_5_19_b",1,"uniequip_002_mlynar",0,0,158,4,79275,11893,172,37,4],
|
||||
["p1",4,"op","chess_char_5_13_b",2,"uniequip_004_ghost2",3412.8,1,9,5,146836,18085,143,21,2],
|
||||
["p1",5,"op","chess_char_5_14_b",2,"none",1994,1,168,11,231063,15046,2302,62,5],
|
||||
["p1",5,"op","chess_char_5_14_b",2,"none",1994,1,168,10,229565,15046,2302,62,5],
|
||||
["p1",6,"op","chess_char_5_17_b",2,"none",153.59,1,162,2,116401,14251,285,50,5],
|
||||
["p1",7,"op","chess_char_5_20_a",1,null,1108,1,3,1,43321,1688,368,361,5],
|
||||
["p1",8,"op","chess_char_5_22_a",2,null,1237,1,79,5,123577,5289,413,112,3],
|
||||
["p1",9,"op","chess_char_5_12_b",2,"uniequip_004_dusk",1667,1,13,8,413532,0,0,63,2],
|
||||
["p1",10,"op","chess_char_5_15_b",2,"uniequip_002_thorn2",1170,1,14,38,1500942,0,0,175,6],
|
||||
["p1",10,"op","chess_char_5_15_b",2,"uniequip_002_thorn2",1170,1,14,39,1500897,0,0,175,6],
|
||||
["p1",11,"op","chess_char_5_20_b",1,"uniequip_004_aglina",1292,1,5,6,139374,1688,368,513,6],
|
||||
["p1",12,"op","chess_char_5_22_b",2,"none",1511,1,11,8,326656,1913,398,155,3],
|
||||
["-","~1","device","trap_1105_accrate",null,null,100,1,1,0,0,0,0,0,null],
|
||||
@@ -2733,10 +2733,10 @@
|
||||
"enemy_1502_crowns": [1,1,0,0,17916],
|
||||
"enemy_2085_skzjxd": [1,0,1,0,27708]
|
||||
},
|
||||
"hooks": [1,169,6392,1856,1856,4793,4802,4572,133,155,47,45,0,25292,2502,134,119,22,1,137,0,0,0],
|
||||
"events": {"atk":2202,"bounty":4,"deploy":48,"die":133,"dmg":4802,"engage":31,"fx":126,"heal":157,"leak":22,"skill":92,"spawn":152,"status":917},
|
||||
"hooks": [1,169,6392,1856,1856,4806,4815,4572,133,155,47,45,0,25292,2500,134,119,22,1,137,0,0,0],
|
||||
"events": {"atk":2201,"bounty":4,"deploy":48,"die":133,"dmg":4815,"engage":31,"fx":126,"heal":157,"leak":22,"skill":92,"spawn":152,"status":917},
|
||||
"fx": {"blink":1,"crit":17,"displace":34,"explode":5,"sp":11,"substitute":4,"summon":19,"swap":3,"teleport":9,"zone":23},
|
||||
"snaps": "a39ea9a8 8c9edc9a a065676e 3404b1b0 c5e48361 e1141ee7 731907d0 35ea8479 ddbaef3d 5482db0f 24f79c23 1a11903e 1f6f9bf4 c6ce73f3 1e9e1c5b 86972b3e 9e39b85b 2ec9de5d e7d5989b 90b52fbd 7a512691 2515b778"
|
||||
"snaps": "a39ea9a8 e80ba854 5a7d8922 937a75f8 63bcd2cc 5b792ef2 74605095 8cde1b64 3d34ce14 0ba6b47a 25291a4a c4759cbb 4f089279 6b4a97f6 a901573a e5a3248f 0e14690a 229cc4f4 ce5e4276 6af66d94 7b8ead38 e61d788d"
|
||||
},
|
||||
"roster-045": {
|
||||
"about": "pass 2 band 6: chess_char_6_03_a chess_char_6_06_a chess_char_6_07_a chess_char_6_01_a chess_char_6_02_a chess_char_6_04_a chess_char_6_05_a chess_char_6_08_a chess_char_6_09_a chess_char_6_11_a chess_char_6_12_a chess_char_6_13_a token_10017_skadi2_dedant",
|
||||
|
||||
@@ -48,7 +48,12 @@ function scenario(chessId, dir, secs) {
|
||||
e_fly: enemyRec({ key: 'e_fly', hp: 1e6, speed: 0, motion: 'FLY', def: 50, res: 30 }),
|
||||
},
|
||||
},
|
||||
setup: (b) => b.on('deploy', ({ unit }) => { if (unit.uid >= 100) unit.hp = unit.s.maxHp * (0.3 + 0.1 * (unit.uid - 100)); }),
|
||||
setup: (b) => {
|
||||
b.on('deploy', ({ unit }) => { if (unit.uid >= 100) unit.hp = unit.s.maxHp * (0.3 + 0.1 * (unit.uid - 100)); });
|
||||
// the open field has no boards: "a tile of the player's own board" (Battle.onOwnBoard — 乌尔比安 S3's landing) is a
|
||||
// board-position rule (DESIGN), not a facing one — every tile counts here, so the anchor's landing turns with him
|
||||
b.onOwnBoard = () => true;
|
||||
},
|
||||
});
|
||||
h.run(secs);
|
||||
checkInvariants(h.b);
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
// test/sim/feedback5-cb3-pins.test.js — community reports of 2026-10-06 that this tree already answers (stream CB3; they pass
|
||||
// on the parent commit — nothing changed for them), pinned:
|
||||
// item 2 「敌人在干员铃兰技能范围内没有开技能,在攻击范围才开」 — 铃兰's default S3 狐火渺然 ("攻击范围扩大") was on the basic
|
||||
// strategy up to 0.1.4 (DEFAULT: an enemy in her own 2-tile range); 0.2.0's ACTIVE_RANGE (the owner's rule of 2026-10-05,
|
||||
// tools/build-data.mjs resolveTrigger) casts it with an enemy inside its running range y-8 (3 tiles ahead).
|
||||
// item 16.1 「突袭转职玛恩纳…攻击范围里有怪的时候即使长时间没攻击也不会突袭」 — the bond text itself: "干员10秒内未进行攻击或技能
|
||||
// 就绪时,若范围内没有敌人,则…再部署": a 解放者 never attacks with his skill off, so his 10 s are always met, and an enemy in
|
||||
// his range is the one thing that holds the jump — as for every member.
|
||||
// item 16.4 「归鲨被吃的时候不是变替身而是进了再部署」 — an 阿戈尔 devour mark on 归溟幽灵鲨 switches her to her 替身 (normal, 联防,
|
||||
// boss fields); never a knock-out (a sweep of 400 random chains on this tree and v0.1.2–v0.1.4: 0).
|
||||
// item 46 「荒芜拉普兰德开技能之后好像没有普攻了…叙拉古恐惧概率不高」 — during her default S3 every drone is out chasing (PRTS
|
||||
// 技能流程), so she makes no attack of her own; her attacks come back when it ends. 叙拉古 6's proc is PRTS's pseudo-random
|
||||
// rule: 0.139 % per 普通伤害 attempt, +0.139 % per miss, shared by the player's members (3 % on average).
|
||||
// Run: node --test test/sim/feedback5-cb3-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 { prdConstant } from '../../server/sim/content/bonds/core.js';
|
||||
|
||||
const ds = getDefaultSource();
|
||||
const dummy = (key, o = {}) => enemyRec({ key, hp: 1e9, speed: 0, mass: 0, atk: 0, ...o });
|
||||
|
||||
test('item 2 — 铃兰 S3 狐火渺然: ACTIVE_RANGE on its y-8; casts with an enemy 3 tiles ahead (outside her own range), not 4', () => {
|
||||
for (const id of ['chess_char_5_10_a', 'chess_char_5_10_b']) {
|
||||
const rec = ds.rawChess(id);
|
||||
const s3 = rec.skills.find((s) => s.skillId === 'skchr_lisa_3');
|
||||
assert.deepEqual([rec.skill.skillId, s3.trigger.rule, s3.trigger.rawRule], ['skchr_lisa_3', 'ACTIVE_RANGE', 'DEFAULT'], `${id}: her default S3`);
|
||||
assert.ok(!rec.rangeGrid.some(([r, c]) => r === 0 && c === 3) && s3.trigger.customRangeGrid.some(([r, c]) => r === 0 && c === 3), `${id}: 3 ahead is in y-8 only`);
|
||||
const casts = (pos) => {
|
||||
const h = makeBattle({ seed: 3, autoFinish: false, timeLimit: 60, defs: { enemies: { enemy_pin: dummy('enemy_pin') } }, units: [{ chessId: id, row: 10, col: 4 }] });
|
||||
h.step();
|
||||
const u = h.unit(id);
|
||||
u.skill.gainSp(999, 'test');
|
||||
h.spawn('enemy_pin', { pos });
|
||||
h.run(3);
|
||||
checkInvariants(h.b);
|
||||
return u.skill.activations;
|
||||
};
|
||||
assert.equal(casts([10, 7]), 1, `${id}: 3 tiles ahead`);
|
||||
assert.equal(casts([10, 8]), 0, `${id}: not 4 tiles ahead`);
|
||||
}
|
||||
});
|
||||
|
||||
test('item 16.1 — a 突袭 玛恩纳 (变形同构体 + 突袭手雷): no jump while an enemy stays in his range ("若范围内没有敌人"); at once when none is', () => {
|
||||
const h = makeBattle({
|
||||
seed: 5, autoFinish: false, timeLimit: 120, hooks: ['deploy'], bonds: { raidShip: { count: 3, active: true, tier: 1, layers: 1 } },
|
||||
defs: { enemies: { enemy_pin: dummy('enemy_pin') } },
|
||||
units: [{ chessId: 'chess_char_5_19_a', row: 10, col: 4, items: ['chess_item_6_09_e_a', 'chess_item_3_11_e_a'] }],
|
||||
});
|
||||
h.step();
|
||||
const u = h.unit('chess_char_5_19_a');
|
||||
const near = h.spawn('enemy_pin', { pos: [10, 5] });
|
||||
h.spawn('enemy_pin', { pos: [12, 8] });
|
||||
const jumps = () => h.hooksOf('deploy').filter((c) => c.unit === u && !c.initial).length;
|
||||
h.run(20);
|
||||
assert.equal(u.lastAttackAt, -Infinity, 'a 解放者 makes no attack with his skill off (his 10 s are met)');
|
||||
assert.equal(jumps(), 0, 'an enemy in his range: no jump');
|
||||
h.b.kill(near, null);
|
||||
assert.ok(h.runUntil(() => jumps() > 0, 1), 'none in range: he jumps at once');
|
||||
checkInvariants(h.b);
|
||||
});
|
||||
|
||||
test('item 16.4 — 归溟幽灵鲨 devoured by an 阿戈尔 (normal, 联防, boss): her 替身 at full HP, never knocked out', () => {
|
||||
for (const kind of ['normal', 'unite', 'boss']) {
|
||||
for (const g of ['chess_char_5_13_a', 'chess_char_5_13_b']) {
|
||||
const row = kind === 'boss' ? 2 : 10;
|
||||
const h = makeBattle({
|
||||
kind, seed: 4, autoFinish: false, timeLimit: 60, captureNoisy: true, hooks: ['damaged', 'death'],
|
||||
bonds: { egirShip: { count: 2, active: true, tier: 1, layers: 0 } },
|
||||
players: [{ playerId: 'p1', seat: 0, side: 'L', colOffset: 0, units: [{ uid: 1, kind: 'chess', chessId: 'chess_char_2_07_a', row: kind === 'boss' ? 9 : 10, col: 4 }, { uid: 2, kind: 'chess', chessId: g, row: kind === 'boss' ? 9 : 10, col: 5 }], bonds: { egirShip: { count: 2, active: true, tier: 1, layers: 0 } } }],
|
||||
});
|
||||
h.step();
|
||||
const u = h.unit(g);
|
||||
assert.equal(u.tileR, row, `${kind}: on the field`);
|
||||
assert.equal(h.hooksOf('damaged').filter((c) => c.target === u && (c.dmg?.tags || []).includes('bond:egir:devour')).length, 1, `${kind} ${g}: one devour mark`);
|
||||
assert.ok(u.alive && u.trait.doll && u.form === 'doll', `${kind} ${g}: her 替身`);
|
||||
assert.ok(Math.abs(u.hp - u.s.maxHp) < 1e-6, `${kind} ${g}: at full HP`);
|
||||
assert.equal(h.hooksOf('death').filter((c) => c.unit === u).length, 0, `${kind} ${g}: no knock-out`);
|
||||
checkInvariants(h.b);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test('item 46 — 荒芜拉普兰德 S3: no attack of her own while her drones are out (they hit), attacks again after; 叙拉古 6 = PRTS\'s 0.139 % pseudo-random', () => {
|
||||
const h = makeBattle({
|
||||
seed: 3, autoFinish: false, timeLimit: 120, captureNoisy: true, hooks: ['attack', 'damaged', 'skillStart', 'skillEnd'],
|
||||
defs: { enemies: { enemy_pin: dummy('enemy_pin', { atk: 50 }) } }, units: [{ chessId: 'chess_char_6_18_a', row: 10, col: 4 }],
|
||||
enemies: [{ key: 'enemy_pin', pos: [10, 4] }],
|
||||
});
|
||||
const u = () => h.unit('chess_char_6_18_a');
|
||||
assert.ok(h.runUntil(() => u().skill.active, 60), 'S3 cast');
|
||||
const t0 = h.b.time;
|
||||
const attacks = () => h.hooksOf('attack').filter((c) => c.attacker === u()).length;
|
||||
assert.ok(h.runUntil(() => !u().skill.active, 45), 'S3 over');
|
||||
const t1 = h.hooksOf('skillEnd').filter((c) => c.unit === u()).at(-1).t;
|
||||
const n0 = attacks();
|
||||
// (the tick that ends the skill already attacks again: strictly inside the window)
|
||||
assert.equal(h.hooksOf('attack').filter((c) => c.attacker === u() && c.t > t0 + 1e-9 && c.t < t1 - 1e-9).length, 0, 'no attack of her own during S3');
|
||||
assert.ok(h.hooksOf('damaged').some((c) => c.source === u() && c.t > t0 && (c.dmg.tags || []).includes('droneAttack')), 'her drones hit');
|
||||
h.run(5);
|
||||
assert.ok(attacks() > n0, 'her attacks resume after the skill');
|
||||
checkInvariants(h.b);
|
||||
const c = prdConstant(0.03);
|
||||
assert.ok(Math.abs(c - 0.00139) < 0.00001, `叙拉古 6 PRD constant ${c} ≈ PRTS 0.139 %`);
|
||||
assert.ok(Math.ceil(1 / c) <= 722, 'a proc by the 722nd attempt at the latest (PRTS: 720 with the rounded 0.139 %)');
|
||||
});
|
||||
@@ -0,0 +1,121 @@
|
||||
// test/sim/feedback5-counters-any-damage.test.js — community report of 2026-10-06 (item 30) 「退行的潮涌者的攻击无法触发菲莱2技能
|
||||
// 的受击反击(排查其他类似技能的干员)」. The enemy is 深溟巢涌者 / 富营养的巢涌者 (the 退行的巢涌者 of the main story): it makes no
|
||||
// normal attack — its talent hurts every operator in range once a second (PRTS "无途径法术伤害"; buff_template_data
|
||||
// enemy_dsubrl_aoe[aura]: an AdvancedApplyDamage with the enemy as its source). The official counters fire on ON_TAKE_DAMAGE —
|
||||
// 菲莱 S2 philae_s_2 with no filter at all, the others on a source of the other side (inverse_damage — 星熊 S2 —,
|
||||
// inverse_damage[magic] + nian_s_2 — 年 S2 —, bubble_s_2 / bubble_t_1 — 泡泡 —, vendla_s_2 — 刺玫 S2 —, yu_s_1[inverse_damage] —
|
||||
// 余 S1 —, hsgma2_s_1 — 斩业星熊 S1 —, mlynar_t_2[inverse] — 玛恩纳 无动于衷) — but the remake took enemy attacks only.
|
||||
// Now any damage instance from an enemy (kits/shared/tier1.js byEnemyAttack; 菲莱: any instance), never a 流失.
|
||||
// Run: node --test test/sim/feedback5-counters-any-damage.test.js
|
||||
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { makeBattle, checkInvariants } from '../helpers/battleHarness.js';
|
||||
|
||||
const NEST = 'enemy_1234_dsubrl';
|
||||
|
||||
/**
|
||||
* `units` on the flat field, a parked 深溟巢涌者 on `nestAt` (speed ×0: it pulses every operator within 1.6 every second and
|
||||
* never attacks); `cast` = the unit whose skill is cast at once. Returns the harness after `seconds`.
|
||||
*/
|
||||
function nestFight(units, { cast = null, nestAt = [10, 5], seconds = 8 } = {}) {
|
||||
const h = makeBattle({ seed: 7, autoFinish: false, timeLimit: 60, captureNoisy: true, hooks: ['damaged', 'attack'], units });
|
||||
h.step();
|
||||
const nest = h.spawn(NEST, { pos: nestAt, mods: { speedMul: 0 } });
|
||||
if (cast) { const u = h.unit(cast); u.skill.gainSp(999, 'test'); if (!u.skill.active) assert.ok(u.skill.activate('test'), `${cast}: cast`); }
|
||||
h.run(seconds);
|
||||
checkInvariants(h.b);
|
||||
return { h, nest };
|
||||
}
|
||||
const fromTo = (h, src, tgt, pred) => h.hooksOf('damaged').filter((c) => c.source === src && c.target === tgt && pred(c));
|
||||
const tagged = (tag) => (c) => (c.dmg?.tags || []).includes(tag);
|
||||
/** The pulses `u` took (the 巢涌者's arts instances; its 神经损伤 rider is an element 损伤, no counter's business). */
|
||||
const pulsesOn = (h, nest, u) => fromTo(h, nest, u, (c) => c.type === 'arts').length;
|
||||
|
||||
test('the 巢涌者 never attacks — its pulse is the only damage it deals (the operators take it)', () => {
|
||||
const { h, nest } = nestFight([{ chessId: 'chess_char_4_17_a', row: 10, col: 4, skillIndex: 1 }]);
|
||||
assert.equal(h.hooksOf('attack').filter((c) => c.attacker === nest).length, 0, 'no normal attack');
|
||||
const pulses = h.hooksOf('damaged').filter((c) => c.source === nest && c.target.side === 'ally');
|
||||
assert.ok(pulses.length >= 3, `pulses ${pulses.length}`);
|
||||
assert.ok(pulses.every((c) => !c.dmg.isAttack), 'not an attack');
|
||||
});
|
||||
|
||||
test('菲莱 S2 冥河诅咒: the pulse sets off her blast (every 2 s at most) — until 0.2.0 it never did', () => {
|
||||
for (const id of ['chess_char_3_06_a', 'chess_char_3_06_b']) {
|
||||
const { h, nest } = nestFight([{ chessId: id, row: 10, col: 4, skillIndex: 1 }], { cast: id });
|
||||
const u = h.unit(id);
|
||||
const n = pulsesOn(h, nest, u);
|
||||
const blasts = fromTo(h, u, nest, tagged('counter'));
|
||||
assert.ok(n >= 4, `${id}: ${n} pulses`);
|
||||
assert.equal(blasts.length, Math.ceil(n / 2), `${id}: ${blasts.length} blasts for ${n} pulses a second apart (aoe_cd 2 s)`);
|
||||
}
|
||||
});
|
||||
|
||||
test('星熊 S2 荆棘, 泡泡 “挨打” (+ 尖刺盾), 余 S1, 玛恩纳 无动于衷: each answers the pulse', () => {
|
||||
const each = (label, f, unitId, pred) => {
|
||||
const u = f.h.unit(unitId), n = pulsesOn(f.h, f.nest, u);
|
||||
assert.ok(n >= 4, `${label}: ${n} pulses`);
|
||||
assert.equal(fromTo(f.h, u, f.nest, pred).length, n, `${label}: one answer per pulse`);
|
||||
};
|
||||
each('星熊 S2 荆棘', nestFight([{ chessId: 'chess_char_4_17_a', row: 10, col: 4, skillIndex: 1 }]), 'chess_char_4_17_a', tagged('counter'));
|
||||
const bb = nestFight([{ chessId: 'chess_char_2_08_a', row: 10, col: 4, skillIndex: 1 }], { cast: 'chess_char_2_08_a' });
|
||||
each('泡泡 S2 “挨打”', bb, 'chess_char_2_08_a', tagged('counter'));
|
||||
assert.ok(bb.nest.findBuff('bubble:spike'), '泡泡 尖刺盾 on the pulse\'s source');
|
||||
// 余 S1 — the 灼燃损伤 rider: once the 巢涌者's gauge bursts, its 爆发冷却 refuses further fills, so count the answers that landed
|
||||
const yu = nestFight([{ chessId: 'chess_char_6_03_a', row: 10, col: 4, skillIndex: 0 }], { cast: 'chess_char_6_03_a' });
|
||||
const yuN = fromTo(yu.h, yu.h.unit('chess_char_6_03_a'), yu.nest, (c) => c.type === 'element').length;
|
||||
assert.ok(yuN >= 3, `余 S1 灼燃损伤: ${yuN} answers`);
|
||||
each('玛恩纳 无动于衷', nestFight([{ chessId: 'chess_char_5_19_a', row: 10, col: 4 }]), 'chess_char_5_19_a', tagged('reflect'));
|
||||
});
|
||||
|
||||
test('刺玫 S2 荆藤庇荫: a pulse on her protégé is answered (the counter names the protégé for her trait heal)', () => {
|
||||
const { h, nest } = nestFight([
|
||||
{ chessId: 'chess_char_1_06_a', row: 10, col: 3, skillIndex: 1 },
|
||||
{ chessId: 'chess_char_4_17_a', row: 10, col: 4, skillIndex: 0 },
|
||||
], { cast: 'chess_char_1_06_a' });
|
||||
const v = h.unit('chess_char_1_06_a'), p = v.mem.protege;
|
||||
assert.ok(p && p.defId === 'chess_char_4_17_a', 'the protégé');
|
||||
const hits = fromTo(h, v, nest, tagged('counter'));
|
||||
const n = pulsesOn(h, nest, p);
|
||||
assert.ok(n >= 4, `${n} pulses on the protégé`);
|
||||
assert.equal(hits.length, n, `one counter per pulse on the protégé (${hits.length})`);
|
||||
assert.ok(hits.every((c) => c.dmg.traitAlly === p));
|
||||
});
|
||||
|
||||
test('自选 年 S2 铜印 and 斩业星熊 S1 恶业苦果 answer the pulse too', () => {
|
||||
const ni = nestFight([{ diy: { slot: 6, charId: 'char_2014_nian', skillIndex: 1 }, row: 10, col: 4 }]);
|
||||
const n = ni.h.allies().find((u) => u.def?.charId === 'char_2014_nian' || u.charId === 'char_2014_nian' || /nian/.test(u.def?.diy?.charId ?? ''));
|
||||
assert.ok(n, '年 fielded');
|
||||
n.skill.gainSp(999, 'test');
|
||||
if (!n.skill.active) n.skill.activate('test');
|
||||
const before = pulsesOn(ni.h, ni.nest, n);
|
||||
ni.h.run(6);
|
||||
assert.ok(fromTo(ni.h, n, ni.nest, tagged('counter')).length >= pulsesOn(ni.h, ni.nest, n) - before && pulsesOn(ni.h, ni.nest, n) - before >= 4, '年 S2');
|
||||
assert.ok(ni.nest.findBuff('silence') || ni.nest.s.flags.silence, '年 S2 silences the source');
|
||||
|
||||
const hm = nestFight([{ diy: { slot: 6, charId: 'char_1044_hsgma2', skillIndex: 0 }, row: 10, col: 4 }]);
|
||||
const s = hm.h.allies()[0];
|
||||
s.skill.gainSp(999, 'test');
|
||||
if (!s.skill.active) s.skill.activate('test');
|
||||
const before2 = pulsesOn(hm.h, hm.nest, s);
|
||||
hm.h.run(6);
|
||||
assert.ok(fromTo(hm.h, s, hm.nest, tagged('counter')).length >= pulsesOn(hm.h, hm.nest, s) - before2 && pulsesOn(hm.h, hm.nest, s) - before2 >= 4, '斩业星熊 S1');
|
||||
});
|
||||
|
||||
test('never a 流失: an enemy\'s HP loss on 星熊 sets no 荆棘 off; another counter / reflection does not either', () => {
|
||||
const h = makeBattle({ seed: 7, autoFinish: false, timeLimit: 60, captureNoisy: true, hooks: ['damaged'],
|
||||
units: [{ chessId: 'chess_char_4_17_a', row: 10, col: 4, skillIndex: 1 }] });
|
||||
h.step();
|
||||
const nest = h.spawn(NEST, { pos: [10, 8], mods: { speedMul: 0 } }); // out of pulse range
|
||||
const u = h.unit('chess_char_4_17_a');
|
||||
u.skill.gainSp(999, 'test');
|
||||
if (!u.skill.active) u.skill.activate('test');
|
||||
h.step();
|
||||
h.b.loseHp(u, 10, { source: nest });
|
||||
h.b.dealDamage(nest, u, { amount: 10, type: 'true', tags: ['counter'] });
|
||||
h.b.dealDamage(nest, u, { amount: 10, type: 'true', tags: ['reflect'] });
|
||||
assert.equal(fromTo(h, u, nest, tagged('counter')).length, 0, 'none of the three');
|
||||
h.b.dealDamage(nest, u, { amount: 10, type: 'true' }); // (true damage: her 战术装甲 negates only phys / arts)
|
||||
assert.equal(fromTo(h, u, nest, tagged('counter')).length, 1, 'a plain damage instance does');
|
||||
checkInvariants(h.b);
|
||||
});
|
||||
@@ -0,0 +1,60 @@
|
||||
// test/sim/feedback5-gravel-double-hit.test.js — community report of 2026-10-06 (item 16.5) 「砾的平A是比较特殊的双判,是两次50%
|
||||
// 伤害倍率(不是攻击倍率),对频次怪的效率应该比正常干员高,但是现在游戏内还是单次判定」: PRTS 砾 特性备注 "在砾的攻击动作下,每次普通攻击造成
|
||||
// 两段伤害,但是每段最终只会造成50%的伤害(在计算防御/减伤后,在重设伤害前);第二段伤害不会触发目标的受击回复". Up to 0.2.0 every attack was
|
||||
// one instance. Now two instances of 50 % 伤害倍率 (DamageInfo `mul`, after DEF — the profile's `hitDmgMul`, ai.js resolveHit).
|
||||
// Run: node --test test/sim/feedback5-gravel-double-hit.test.js
|
||||
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { makeBattle, enemyRec, checkInvariants } from '../helpers/battleHarness.js';
|
||||
import { hitCount } from '../../server/sim/content/enemies/helpers.js';
|
||||
import { MIN_DAMAGE_RATIO } from '../../server/sim/constants.js';
|
||||
|
||||
const near = (a, b, msg) => assert.ok(Math.abs(a - b) <= 1e-6, `${msg}: ${a} vs ${b}`);
|
||||
|
||||
/** 砾 on (10,4) facing right, one parked enemy on (10,5); returns her attacks and her damage instances on it. */
|
||||
function fight(id, enemy, seconds = 5) {
|
||||
const h = makeBattle({
|
||||
seed: 2, autoFinish: false, timeLimit: 60, captureNoisy: true, hooks: ['damaged', 'attack'],
|
||||
defs: { enemies: { enemy_g: enemyRec({ key: 'enemy_g', hp: 1e9, speed: 0, mass: 0, ...enemy }) } },
|
||||
units: [{ chessId: id, row: 10, col: 4 }],
|
||||
});
|
||||
h.step();
|
||||
const e = h.spawn('enemy_g', { pos: [10, 5] });
|
||||
return { h, e, run: () => h.run(seconds) };
|
||||
}
|
||||
|
||||
test('砾 (normal, elite): every normal attack is two damage instances of 50 % 伤害倍率 after DEF — the same total, not 50 % 攻击倍率', () => {
|
||||
for (const id of ['chess_char_2_12_a', 'chess_char_2_12_b']) {
|
||||
for (const def of [0, 300, 5000]) {
|
||||
const { h, run } = fight(id, { def });
|
||||
run();
|
||||
const u = h.unit(id);
|
||||
const attacks = h.hooksOf('attack').filter((c) => c.attacker === u).length;
|
||||
const hits = h.hooksOf('damaged').filter((c) => c.source === u && c.dmg?.isAttack);
|
||||
assert.ok(attacks >= 3, `${id}: she attacks (${attacks})`);
|
||||
assert.equal(hits.length, 2 * attacks, `${id} DEF ${def}: two instances per attack`);
|
||||
const atk = u.s.atk;
|
||||
const full = Math.max(atk - def, MIN_DAMAGE_RATIO * atk); // one instance of the whole attack, after DEF
|
||||
for (const c of hits) near(c.amount, 0.5 * full, `${id} DEF ${def}: each instance is 50 % of the mitigated hit`);
|
||||
// first instance of each attack may give 受击回复, the second may not
|
||||
const byAttack = new Map();
|
||||
for (const c of hits) { const l = byAttack.get(c.dmg.attackId) ?? []; l.push(c); byAttack.set(c.dmg.attackId, l); }
|
||||
for (const l of byAttack.values()) assert.deepEqual(l.map((c) => !!c.dmg.noSp), [false, true], `${id}: the second instance carries no 受击回复`);
|
||||
checkInvariants(h.b);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test('砾 against a 频次 enemy: two counted hits per attack (one before 0.2.0)', () => {
|
||||
for (const id of ['chess_char_2_12_a', 'chess_char_2_12_b']) {
|
||||
const { h, e, run } = fight(id, { hp: 100 });
|
||||
hitCount(h.b, e, true);
|
||||
run();
|
||||
const u = h.unit(id);
|
||||
const attacks = h.hooksOf('attack').filter((c) => c.attacker === u).length;
|
||||
assert.ok(attacks >= 3, `${id}: she attacks`);
|
||||
assert.equal(100 - e.hp, 2 * attacks, `${id}: 2 per attack`);
|
||||
checkInvariants(h.b);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,79 @@
|
||||
// test/sim/feedback5-raid-revive.test.js — community report of 2026-10-06 (item 44) 「突袭盟约的干员如果带被动技能,复活之后不会
|
||||
// 立马突袭出去,还要等突袭CD」. A 突袭 member counts a running deploy-timed skill ("部署后…秒内": 缄默德克萨斯 S1–S3 …) as 技能
|
||||
// 就绪 (bonds/addon/battle.js raidPoll, GitHub #49 / #109), so after a redeploy it jumps at once when nothing is in its range.
|
||||
// PRTS's 复活 (M3茧甲, 埃芒加德) is 退场 + a 0-time / 0-cost redeploy (PRTS 盟约记录 备注) — a new deployment — but the remake
|
||||
// revives in place: her window, over by then, stayed over and she waited out the 10 s idle time. Now an in-place revive
|
||||
// starts a deploy-timed skill again (content/items/battle.js revivedInPlace); 不屈's real redeploy already did.
|
||||
// Run: node --test test/sim/feedback5-raid-revive.test.js
|
||||
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { makeBattle, enemyRec, checkInvariants } from '../helpers/battleHarness.js';
|
||||
|
||||
const TEX = 'chess_char_4_16_a';
|
||||
const DUMMY = { enemy_rv: enemyRec({ key: 'enemy_rv', hp: 1e9, speed: 0, mass: 0, atk: 0 }) };
|
||||
const RAID = { raidShip: { count: 3, active: true, tier: 1, layers: 10 } };
|
||||
|
||||
/**
|
||||
* 缄默德克萨斯 (S3, a 6 s deploy-timed skill) in 突袭 with `extra` (items / band): she jumps to a parked enemy, stays past her
|
||||
* window, the enemy is removed, she is knocked out with nothing in range, a new enemy parks away from her. Returns how long
|
||||
* after the knock-out her next jump comes (null: none within 15 s) and her skill state right after the revive.
|
||||
*/
|
||||
function reviveAndJump({ items, bandId = null, bonds = {} }) {
|
||||
const h = makeBattle({
|
||||
seed: 3, autoFinish: false, timeLimit: 120, hooks: ['deploy', 'death'], defs: { enemies: DUMMY }, bandId,
|
||||
bonds: { ...RAID, ...bonds }, enemies: [{ key: 'enemy_rv', pos: [9, 9] }], units: [{ chessId: TEX, row: 12, col: 3, skillIndex: 2, items }],
|
||||
});
|
||||
h.step();
|
||||
const u = h.unit(TEX);
|
||||
const jumps = () => h.hooksOf('deploy').filter((c) => c.unit === u && !c.initial);
|
||||
assert.ok(h.runUntil(() => jumps().length >= 1, 10), 'her first jump');
|
||||
h.run(8);
|
||||
assert.equal(u.skill.active, false, 'her 6 s window is over');
|
||||
for (const e of h.b.enemies.filter((x) => x.alive)) h.b.kill(e, null);
|
||||
const t0 = h.b.time;
|
||||
h.b.dealDamage(null, u, { amount: 1e9, type: 'true' });
|
||||
h.spawn('enemy_rv', { pos: [12, 9] });
|
||||
h.step();
|
||||
const state = { alive: u.alive, active: u.skill.active, timeLeft: u.skill.timeLeft };
|
||||
const n = jumps().length;
|
||||
const jumped = h.runUntil(() => jumps().length > n && u.tileR === 12, 15);
|
||||
checkInvariants(h.b);
|
||||
return { after: jumped ? h.b.time - t0 : null, state, u, h };
|
||||
}
|
||||
|
||||
test('M3茧甲 / 埃芒加德 revive 缄默德克萨斯 in place: her deploy-timed S3 runs again and she jumps at once (until 0.2.0 only after the 10 s idle)', () => {
|
||||
for (const [label, opts] of [['M3茧甲', { items: ['chess_item_4_12_e_a'] }], ['埃芒加德', { bandId: 'band_ermengard' }]]) {
|
||||
const { after, state } = reviveAndJump(opts);
|
||||
assert.ok(state.alive, `${label}: revived in place`);
|
||||
assert.ok(state.active, `${label}: her deploy-timed S3 runs again`);
|
||||
assert.ok(after != null && after < 1, `${label}: jumped ${after?.toFixed(2)} s after the knock-out`);
|
||||
}
|
||||
});
|
||||
|
||||
test('不屈\'s 立刻重新部署 (a real redeploy) already jumped at once — unchanged', () => {
|
||||
const { after } = reviveAndJump({ bonds: { indomShip: { count: 2, active: true, tier: 1, layers: 300 } } });
|
||||
assert.ok(after != null && after < 1, `jumped ${after?.toFixed(2)} s after the knock-out`);
|
||||
});
|
||||
|
||||
test('an in-place revive inside the window sets it back to its full length; 砾 revived by M3茧甲 gets a fresh barrier', () => {
|
||||
const h = makeBattle({ seed: 3, autoFinish: false, timeLimit: 60, units: [{ chessId: TEX, row: 12, col: 3, skillIndex: 2, items: ['chess_item_4_12_e_a'] }] });
|
||||
h.step();
|
||||
const u = h.unit(TEX);
|
||||
h.run(3);
|
||||
assert.ok(u.skill.active && u.skill.timeLeft < u.skill.duration - 2, 'half-way through the window');
|
||||
h.b.dealDamage(null, u, { amount: 1e9, type: 'true' });
|
||||
h.step(2);
|
||||
assert.ok(u.alive && u.skill.active && u.skill.timeLeft > u.skill.duration - 0.2, `back to the full ${u.skill.duration} s (${u.skill.timeLeft.toFixed(2)})`);
|
||||
checkInvariants(h.b);
|
||||
|
||||
const g = makeBattle({ seed: 3, autoFinish: false, timeLimit: 60, units: [{ chessId: 'chess_char_2_12_a', row: 10, col: 4, items: ['chess_item_4_12_e_a'] }] });
|
||||
g.step();
|
||||
const gr = g.unit('chess_char_2_12_a');
|
||||
g.run(12);
|
||||
assert.ok(!gr.findBuff('gravel:rats'), 'the deployment barrier has run out');
|
||||
g.b.dealDamage(null, gr, { amount: 1e9, type: 'true' });
|
||||
g.step(2);
|
||||
assert.ok(gr.alive && gr.findBuff('gravel:rats')?.shield > 0, 'a fresh barrier after the revive');
|
||||
checkInvariants(g.b);
|
||||
});
|
||||
@@ -0,0 +1,63 @@
|
||||
// test/sim/feedback5-ulpia-own-board.test.js — community report of 2026-10-06 (item 27) 「乌尔比安使用3技能会在联防阶段跳到红门
|
||||
// 后」. 乌尔比安 S3 必须开辟的通路 throws the anchor up to 6 tiles ahead (the nearest enemy of the line, else the farthest tile) and
|
||||
// moves there when the tile "可以部署" (PRTS 备注 ③: the landing tile > the tile one beyond > his own tile). On the one-helper 联防
|
||||
// map (act1autochess_escaped_single: the helper's pieces on the left half, the enemies out of the middle gate at col 10) the
|
||||
// right half is no tile his player deploys on, yet an anchor that met no enemy flew there and he moved behind the red gate for
|
||||
// the whole skill. Now the landing must lie on his own board (Battle.onOwnBoard, the board region mapped onto the field).
|
||||
// Run: node --test test/sim/feedback5-ulpia-own-board.test.js
|
||||
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { makeBattle, enemyRec, checkInvariants } from '../helpers/battleHarness.js';
|
||||
|
||||
const ULPIA = 'chess_char_5_05_a';
|
||||
const dummy = enemyRec({ key: 'enemy_anchor_dummy', hp: 1e9, speed: 0, mass: 0, atk: 0 });
|
||||
|
||||
/** 乌尔比安 cast S3 on `tile` of `kind`'s field; `enemy` = a parked enemy's tile or null. Returns where he stands after the cast. */
|
||||
function cast({ kind = 'unite', stageId = 'act1autochess_escaped_single', tile = [10, 7], enemy = null, colOffset = 0 } = {}) {
|
||||
const h = makeBattle({
|
||||
kind, stageId, seed: 5, autoFinish: false, timeLimit: 120, defs: { enemies: { enemy_anchor_dummy: dummy } },
|
||||
players: [{ playerId: 'p1', seat: 0, side: 'L', colOffset, units: [{ uid: 1, kind: 'chess', chessId: ULPIA, row: tile[0], col: tile[1] }], bonds: {} }],
|
||||
});
|
||||
h.step();
|
||||
const u = h.unit(ULPIA);
|
||||
const home = [u.tileR, u.tileC];
|
||||
if (enemy) { h.spawn('enemy_anchor_dummy', { pos: enemy }); h.step(); } // (one tick: the enemy joins the tile index)
|
||||
u.skill.gainSp(999, 'test');
|
||||
// (its CUSTOM_RANGE trigger waits for an enemy on the line: with none the cast is made by hand, as a player's would be)
|
||||
if (!u.skill.active) assert.ok(u.skill.activate('test'), 'S3 cast');
|
||||
h.run(0.2);
|
||||
const at = [u.tileR, u.tileC];
|
||||
checkInvariants(h.b);
|
||||
return { h, u, home, at };
|
||||
}
|
||||
|
||||
test('one-helper 联防: an anchor that meets no enemy flies on past the middle gate — he stays on his own half (until 0.2.0 he moved behind the red gate)', () => {
|
||||
const { h, u, home, at } = cast({ tile: [10, 7] });
|
||||
assert.deepEqual(home, [10, 7]);
|
||||
assert.ok(h.b.rect.c1 >= 13, 'the 联防 field spans both halves');
|
||||
assert.deepEqual(at, home, `stays on (10,7) — not ${at}`);
|
||||
assert.ok(h.b.onOwnBoard(u.player, 10, 7) && !h.b.onOwnBoard(u.player, 10, 13), 'cols 11+ are not his board');
|
||||
assert.equal(h.b.allyUnits.filter((a) => a.kind === 'token' && a.alive).length, 0, 'no 从不混淆的方向: nothing to return from');
|
||||
});
|
||||
|
||||
test('one-helper 联防: an enemy on his half still draws the anchor and he moves next to it (own board)', () => {
|
||||
const { at } = cast({ tile: [10, 4], enemy: [10, 8] });
|
||||
assert.deepEqual(at, [10, 8], 'he moves onto the anchor tile on his half');
|
||||
});
|
||||
|
||||
test('two-helper 联防: the left helper never lands on the right helper\'s half; the right helper moves on its own half', () => {
|
||||
const left = cast({ stageId: 'act1autochess_escaped_multi', tile: [10, 7] });
|
||||
assert.deepEqual(left.at, left.home, `left helper stays (${left.at})`);
|
||||
// the right-hand helper (colOffset 8): board col 3 → field col 11, enemy 3 tiles ahead on its own half
|
||||
const right = cast({ stageId: 'act1autochess_escaped_multi', tile: [10, 3], colOffset: 8, enemy: [10, 14] });
|
||||
assert.deepEqual(right.home, [10, 11]);
|
||||
assert.deepEqual(right.at, [10, 14], 'moves on its own half');
|
||||
assert.ok(right.h.b.onOwnBoard(right.u.player, 10, 14) && !right.h.b.onOwnBoard(right.u.player, 10, 7));
|
||||
});
|
||||
|
||||
test('a normal battle is unchanged: the anchor stops at the field edge and he moves onto the farthest tile of his board', () => {
|
||||
const { at, h, u } = cast({ kind: 'normal', stageId: 'flat', tile: [10, 3] });
|
||||
assert.deepEqual(at, [10, 9], `6 tiles ahead, the last road tile before the gate column (${at})`);
|
||||
assert.ok(h.b.onOwnBoard(u.player, 10, 9));
|
||||
});
|
||||
@@ -167,6 +167,21 @@ export function pickUnitSfx(banks, opts = {}) {
|
||||
};
|
||||
const exact = (event) => ['attack', 'combat'].map((ab) => banks.get(`${event}.${ab}`)).find((p) => p?.length && ok(p)) ?? null;
|
||||
const own = (p) => (p?.length && ok(p) ? p : null);
|
||||
// operators whose default mode is the unsuffixed ability (a plain attack / combat bank of any event): every numbered
|
||||
// variant (attack.1, attack.2 …) is then a skill mode's ability, whatever its file name — 银灰's attack.2 swing
|
||||
// p_atk_silver_n is his S3 mode's (charpack modes Default / S2 / S3), his normal attack is the Default mode's Combat (impact
|
||||
// ON_ABILITY_HIT.combat p_imp_spear_n, no swing bank): community report of 2026-10-06 (item 54) 「银灰的普通攻击的音效错误
|
||||
// 的使用了3技能期间的攻击音效」. Only the plain banks then, or the operator's own projectile banks; newer operators number
|
||||
// their default mode too (attack.0 …) and keep the rule below
|
||||
if (opts.operator && ['ON_ABILITY_START', 'ON_ABILITY_ON', 'ON_ABILITY_HIT'].some((e) => exact(e))) {
|
||||
const swing = exact('ON_ABILITY_START') ?? exact('ON_ABILITY_ON') ?? own(proj.born);
|
||||
const impact = exact('ON_ABILITY_HIT') ?? own(proj.hit);
|
||||
if (swing) out.attack = swing;
|
||||
if (impact) out.hit = impact;
|
||||
if (banks.get('ON_UNIT_DEAD')?.length) out.die = banks.get('ON_UNIT_DEAD');
|
||||
if (banks.get('ON_UNIT_BORN')?.length) out.born = banks.get('ON_UNIT_BORN');
|
||||
return out;
|
||||
}
|
||||
// operators: the plain ability of either event before any numbered variant
|
||||
const plain = opts.operator ? exact('ON_ABILITY_START') ?? exact('ON_ABILITY_ON') : null;
|
||||
const attack = plain
|
||||
|
||||
Reference in new issue
Block a user