feedback5: merge CB4 — community reports (enemies / bosses): a 突袭 member lands only on its own player's board (never a boss field's hand / 临时整备区 rows nor the other half of a 联防 or boss field), a silenced 萨卡兹枯朽战士 leaves no 污染秽蚀, 萨卡兹穿刺手's acceleration ends with a stun or 束缚 and its first hit after a block adds move speed × 600 as its own instance, 自制投石机 ignores its block when it picks a target (no attack on the 排气格栅's hidden blocker), the briefing types' 7–9 waves, 新硎's 断刃, a freed prisoner in 联防, 鸭爵's 0–2 swaps and the moving leaders' routes pinned, four reports not reproduced; §25.18; golden: vs feedback5 CB4's own rules — roster-016, boss-boss_2/3/4/5/6-pair, hidden-boss_8/10-pair, standin-04/06/08, diy-028, diy-124, matches solo-NORMAL-1, solo-HARD-1, solo-ABYSS-1, coop2-HARD-4, coop4-ABYSS-7, coop2-NORMAL-8-serverrun; vs CB4 exactly what feedback5 changed since its base (CB2's roster 13 / bonds 7 / fields 6, CB5's 18 bot matches)
Merge fix: test/sim/facing-invariance.test.js — the 突袭 rotation check put its enemy on the board's top row (9, 9), so the facing-RIGHT landing tile it expected, (8, 8), lies above the player's board, where CB4's onOwnBoard rule (the official 再部署 goes where the player deploys; community reports 40 / 16.3) now refuses it; the member landed on (10, 8). The enemy stands at (10, 6), inside rows 9–12 / cols 2–10, so all four diagonal tiles are candidates in every direction and the test checks the facing tie-break as before. It failed on fb5-cb4 itself (the stream did not run the file). The §25 intro's stream lines joined into one sentence again. Golden moves outside CB4's commit list are its rules on feedback5's paths (instrumented): solo-HARD-1 and solo-ABYSS-1 now have silenced 枯朽战士 deaths (8 / 15) and 突袭 candidates the own-board filter refuses; coop2-ABYSS-10-boosted, coop2-NORMAL-3 and coop2-NORMAL-14-standins (in CB4's list) have no silenced 枯朽战士 death on this path, and their digests are identical with the own-board filter switched off (the refused tiles were never the chosen ones). Gate: non-browser suites 4968 / 4968, npm run golden ok, test/golden.test.js 9 / 9, lint 0 errors, check:imports ok, typecheck ok, docs-consistency + docs-paths 31 / 31.
This commit is contained in:
commit
6ed3aed335
23 files changed
+1364
-598
No files matched your search
+1
-1
@@ -16,7 +16,7 @@
|
||||
|
||||
| 阶段 | 说明 |
|
||||
|---|---|
|
||||
| 确认本局信息 | 本局地图(标准模拟固定为「战场#01」;险境从 8 张地图中随机,绝境 / 终极从不含战场#01 的 7 张中随机)、敌方派系、**被禁用的盟约及其干员**、领袖预告。所有人确认后继续;同盟模拟最多 25 秒;只有你一名玩家时(独立模拟,或同盟模拟只带 AI 队友)不限时。 |
|
||||
| 确认本局信息 | 本局地图(标准模拟固定为「战场#01」;险境从 8 张地图中随机,绝境 / 终极从不含战场#01 的 7 张中随机)、敌方派系(三种特训敌人类型,如折射、飞行:和官方一样,每种占全局 15 个回合位中的 3 个,第 14 回合领袖战和第 15 回合隐秘核心也各占一个位,所以险境 / 绝境 / 终极第 1–13 回合中有 7–9 波是这三种类型、每种最多 3 波,其余各波是「特异」类型;每波只有一种类型)、**被禁用的盟约及其干员**、领袖预告。所有人确认后继续;同盟模拟最多 25 秒;只有你一名玩家时(独立模拟,或同盟模拟只带 AI 队友)不限时。 |
|
||||
| 选择策略 | 40 名策略(分队长)决定**初始目标生命值(20–45)**和一条永久规则。同盟:随机顺序轮流选,**每人 30 秒**,右上角和「决策中」显示同一个倒计时;AI 队友立即选完;队友已选的不能重复,每人可**跳过一次**(排到最后);超时自动选你**当前选中**的策略(已被队友选走则选华法琳)。独立:自由选择、不限时;同盟模拟只有你一名玩家时也不限时。选的时候可以点左侧决策顺序下方的「查看禁用盟约与干员」,再看一遍「确认本局信息」里的盟约(置灰、禁用人数)和本局禁用干员:只能查看,倒计时照常走,底部也显示轮到谁和剩余秒数;点「关闭」、点窗口外面或按 Esc 关闭,轮到下一位时会自动关闭。 |
|
||||
| 机变 | 部分回合开始前出现:同盟共 6 张卡轮流各取 1 张(首位 30 秒,其余 16 秒;只有你一名玩家时不限时),独立 3 选 1。卡片包括装备、资金、干员、盟约层数、悬赏等;**悬赏决策**为你的作战添加悬赏敌人,卡上用蓝字标出持续多久:「下场作战」/「接下来两场作战」的只出现一场或两场,之后不再出现;官方的「多轮悬赏」(原文写「之后的每场作战」)在这里也按「接下来两场作战」处理,只出现两场(如教鞭的法术大师A2·多轮战术特训)。各回合的悬赏决策按官方对局截图来出:第 3 回合是 6 张「接下来两场作战」的悬赏(3 张 1 资金、2 张 2 资金、1 张 3 资金);第 9 回合是各首领的「下场作战」悬赏和「源石虫·特训」;绝境 / 终极的第 11 回合多半是悬赏决策(也可能是机密商店或战术决策),其中的悬赏通常有 1 只特异巨兽,其余是各阵营的「下场战斗」悬赏。击倒悬赏敌人的人(联防中的队友也算)获得资金;右侧效果栏会写「还剩 N 场作战」。**机密商店**的 6 件装备都免费,和官方一样可能出现两件相同的装备(各算一张卡,可以分别被选走);第 11 回合(绝境 / 终极)的机密商店按官方:2 件 VI 阶、至少 1 件 V 阶和 1 枚盟约之币,标准 / 险境较早回合的机密商店各阶装备都可能出现。**战术决策**也和官方一样可能出现两张相同的卡(官方截图里出现过两张「补给」;各算一张卡,可以分别被选走,每张只生效一次,两人各选一张全队卡则效果叠加);第 11 回合(绝境 / 终极)的战术决策按官方截图只出盟誓、驰援、列装 / 财富 / 补给 / 整备 / 升华等增益卡,不出削弱敌人的卡和战场演变卡。每张卡左上是图标和名称,下面写着完整效果(与详情卡相同的官方描述,手机上也显示);已被选走的卡变暗,右上角显示选走它的玩家头像(悬停可看名字)。选卡要**点两次**:第一次只选中(金框 +「确认选择 · 再次点击」),再点同一张或点右上的「确认选择」才生效;点别的卡换选,按 Esc 或点空白处取消。 |
|
||||
| 休整期 | 购买、摆阵、配装备、冻结 / 刷新、升级调度中心;同盟有倒计时(65–215 秒,随回合增加);独立模拟、以及只有你一名玩家(只带 AI 队友)的同盟模拟不限时。所有人「准备就绪」即提前开战,全员就绪前可取消。 |
|
||||
|
||||
+6
-3
@@ -274,7 +274,8 @@ MELEE enemy only ever hits its blocker — data/enemies.json already zeroes thei
|
||||
for any source; content may set `enemy.profile.melee = false`). Target order
|
||||
(targeting.js `sortAllyTargets`, PRTS 作战机制 索敌 "阻挡→特殊优先级→仇恨值(更容易被攻击→…→最后部署的目标→不容易被攻击)"):
|
||||
its blocker → highest taunt level → latest deployed (`aggroSeq` = the deploy order: a redeploy or a mid-battle summon is the
|
||||
latest). `enemy.profile.canTarget(ally)` (content: 萨卡兹枯朽战车 "只攻击位于低地的我方单位,且不会攻击飞行单位", 掠海漂移体 / “萨科塔之眼” 不会攻击飞行单位 …) filters the candidates before the order;
|
||||
latest) — except an enemy whose 索敌不受阻挡影响 (`enemy.profile.blockFree`: 自制投石机), which selects among the allies in
|
||||
reach as if unblocked, no blocker first (DESIGN §25.18). `enemy.profile.canTarget(ally)` (content: 萨卡兹枯朽战车 "只攻击位于低地的我方单位,且不会攻击飞行单位", 掠海漂移体 / “萨科塔之眼” 不会攻击飞行单位 …) filters the candidates before the order;
|
||||
a special priority (假想敌:铳 / 昆图斯 highest DEF, 假想敌:胄 highest / lowest ATK, “自在” nearest …) sorts by its key and
|
||||
breaks ties by taunt, then latest deployed (`aggroCmp`); `untargetable` / sleeping allies and devices are never targets;
|
||||
an airborne ally (起飞, flag `liftoff`: 蒂比's skills) never for a ground enemy (对地规避 — `targeting.js evadesGround`,
|
||||
@@ -288,7 +289,8 @@ took off (出血, 沙狱, burning DoTs, 淤困, 【自然涌动】 — a tick se
|
||||
sourceless 毒雾 of 假想敌:蚀裂 still reach it [ASSUMED]; a ground enemy's area skill whose cast depends on allies nearby counts only the targets of its trigger
|
||||
selection — 卢西恩's 【aoe】 ("需要目标"), 锏's CircleAttack (`targetsNear`, PRTS 选择器 "所有触发选择器通常不无视迷彩");
|
||||
a stealthed ally (隐匿, 排气格栅) only for the enemy it blocks — our operators keep 隐匿 while blocking (PRTS 作战机制
|
||||
§隐匿; 索敌的概念: a blocked enemy "强行无视对方可选性" attacks its blocker); a camouflaged one (迷彩, flag `camou`: ba.camou
|
||||
§隐匿; 索敌的概念: a blocked enemy "强行无视对方可选性" attacks its blocker) — except an enemy whose 索敌不受阻挡影响
|
||||
(profile `blockFree`: 自制投石机 — it selects as if unblocked, by 仇恨值, so a 隐匿 blocker is no target; DESIGN §25.18); a camouflaged one (迷彩, flag `camou`: ba.camou
|
||||
"不阻挡时不成为敌方普通攻击的目标") likewise (PRTS 异常效果: neither anomaly is "阻挡时解除") — for every target selection
|
||||
(attacks, skill picks, cast conditions, a normal attack on every operator in range — 斩胄之剑 / 破胄之锤's hover attack,
|
||||
“灵幛”). **Enemy area effects** — splash, death and self blasts, area skills and statuses, pulses, the zones an enemy
|
||||
@@ -338,7 +340,7 @@ enemy: 隐匿 kept out, 起飞 not), 【污染秽蚀】 on every ally inside (fl
|
||||
`alliesInRadius`) — through `dealDamage`, so shields absorb a damage
|
||||
tick, damage-taken modifiers scale it and it counts for 受击回复 SP and TAKE_DAMAGE skills like any hit (§4; element fills
|
||||
excepted). 【污染秽蚀】 (萨卡兹枯朽战车's 秽蚀轰击,
|
||||
萨卡兹枯朽战士's death) is **true** damage, 50 / 25 per second on low / high ground (PRTS "每秒受到50/25点真实普通伤害 …
|
||||
萨卡兹枯朽战士's death — none when it dies silenced, its client template checks 沉默, DESIGN §25.18) is **true** damage, 50 / 25 per second on low / high ground (PRTS "每秒受到50/25点真实普通伤害 …
|
||||
同名效果不叠加", user playtest #6): a unit covered by several zones takes one tick per second (`unit.mem.pollutedAt`), so
|
||||
a crowd of dying 萨卡兹枯朽战士 totals 50 / s, not 50 × n. It is "可对空,无视无法选择": it also burns an airborne 起飞 ally
|
||||
(`ignoreSelect`), at the low-ground rate on a low tile. The other zones are no exception to 对地规避: a ground enemy's
|
||||
@@ -829,6 +831,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) |
|
||||
| `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 |
|
||||
|
||||
@@ -122,7 +122,7 @@ Engine helpers (content must use these, never touch internals): `battle.dealDama
|
||||
- **Blocking** (contact radius, PRTS 游戏数据基础 §阻挡半径 / 作战机制 "中点判定…案例:阻挡"; `constants.js BLOCK_RADIUS`, `Battle._checkBlock`, §19.2): an operator with free capacity blocks an unblocked, blockable enemy whose position lies within its block radius of its centre — ground 0.7071 (squared 0.49999037), 0.8944 × the blocker's 阻挡半径倍率 for blockFly units vs flyers (起飞; mod `blockRadiusScale` = 倍率 − 1 — PRTS 游戏数据基础 "飞行阻挡半径 = 0.8944 × 阻挡半径倍率", 凯尔希·思衡托 +0.23), devices 0.4472 (阻隔工事 / 障碍物); air units (FLY, 近地悬浮, 浮空) only by blockFly units. A ground enemy is never blocked by a unit standing on a tile ground units cannot pass (围墙 / 围栏: PRTS 地形机制 "部署在其中的单位,若当前阻挡类型为'地面阻挡'则无法阻挡敌人" — an enemy pushed or pulled against the fence walks on; air blocking there stays [ASSUMED], §21.23) nor by an airborne (起飞) unit, which blocks flyers only (§21.22). An enemy holding 不可阻挡 (PRTS 异常效果 BLOCK_FREE 「无法阻挡/被阻挡,自动解除阻挡」) — `unblockable` (恐惧, 诱导, enemy abilities), 浮空, and 沉睡 (SLEEPING = 无法行动+无敌+不可阻挡) — is never blocked and is released at once: a sleeping enemy frees its blocker's slot, stays where it is and, once awake, is blocked again only by a blocker with room (§24.9). The nearest such operator wins (ties: scan order [ASSUMED]). It is re-checked every tick, moving or not, so another operator in contact with room takes the enemy over when its blocker dies, is withdrawn or is stunned, and an operator whose capacity frees up grabs an overlapping enemy; one that finds no room walks on. A head-on enemy stops at contact (≈ 0.71 tile), outside the blocker's tile. Enemy uses `blockCnt` capacity (default 1). Blocked enemies stop moving and attack their blocker if melee (or anyone in range if ranged, blocker first). **Every blocker** — melee units (重装要塞 / 领主 / 哨戒铁卫 included), summons and a ranged operator on a melee tile alike — whose attack hits enemies may always target the enemies it blocks, in range or not, whatever its facing, and targets them first ("可以选择且优先选择阻挡单位", PRTS 选择器; the user's rule after playtest #6, "阻挡了就一定要能打到": officially the collision pushes a blocked enemy to its blocker's front; `Battle.blockedTargets`, `targeting.js sortEnemyTargets`; §20.3 — it replaces the playtest #5 QA's melee-only restriction of §19.2). A healer (dmgType `heal`, or a skill attack turned into a heal) selects injured allies only and keeps healing while it blocks (PRTS 卫戍协议/帮助 "对于医疗干员(咒愈师分支除外),攻击目标为需要治疗的单位"; §21.17); 咒愈师 follow the blocker rule. The huge leaders are 自缚 + unblockable (§7).
|
||||
- **Operator attacks**: every `interval` s if a valid target exists; targets = up to `maxTargets` (default 1) from `unitsInGrid(rangeGrid)` (a `rangeAoe` profile — 阵法术师, 轰击术师 — takes every selectable enemy in range, §21.18; 「同时攻击阻挡的所有敌人」 — 强攻手 / 重剑手 / 推击手 and the skills worded so, `hitAllBlocked` — up to the block count, never fewer than 1, since 0.2.0: PRTS 分支特性信息 "普通攻击最大目标数等于阻挡数(不会低于1)"), priority: (1) the enemies it blocks (every blocker, in range or not, §20.3), (2) profession/trait priorities (e.g. fly-first snipers, `trait` text parsed by build-data into `targetPriority`), (3) enemy with the **least remaining path distance** to its goal, ties → earliest spawned. Melee (no ranged trait) and ground-only attacks cannot hit air units (`Unit.isFlying`: FLY, or a 近地悬浮 / 浮空 enemy — PRTS "算作空中单位", §19.1). Stealthed enemies can't be targeted unless blocked or revealed — or within 3 s of a block's end (§22.8). Ranged ops fire projectiles (speed ~12 tiles/s, instant for melee/arts-beam classes as data indicates); damage applies on impact; a 锁定攻击范围 AoE (`rangeAoe`) strikes every selectable enemy on its range at once with instant hits (§21.18).
|
||||
- **Healers** (`dmgType heal`): target the ally in range with the lowest HP% below 100%, never a 禁疗 / 孤立 unit (tokens.json `abnormal`, `noHeal`; §20.3; 史尔特尔 during 余烬, §22.7), and never the enemies they block — also while blocking (§21.17); do nothing otherwise (SP still regenerates).
|
||||
- **Enemy AI**: follow the route (checkpoints; WALK paths recomputed on the grid when devices change); when blocked stop & fight (`dmgType 'none'` enemies never attack unless content arms them through `e.profile` — 转译基底's armed forms, §21.4); ranged enemies (`rangeRadius > 0`) attack ops whose 0.25 collider touches their radius (centre distance ≤ `rangeRadius` + 0.25, §3, §20.4): the enemy's own target rule filters the candidates first (`profile.canTarget`: 只攻击地面单位 …), then priority blocker → special priority → highest taunt → **latest deployed** (`aggroSeq`) — PRTS 索敌 "阻挡→特殊优先级→仇恨值→最早出现"; a stealthed ally is attacked only by the enemy it blocks (§19.1), and an enemy's area effects — splash, blasts, area skills, zones, jumps — and buff auras skip it unless it blocks that enemy, while 迷彩 does not protect from splash and the other area effects (`targeting.js areaSelectable` / `auraSelectable`, §22.12); an airborne (起飞) ally is never a ground enemy's selection — picks, area damage, zones and statuses skip it, while 无视无法选择 abilities, direct picks, debuff ticks and flying units still reach it (§21.22); unblocked, they stand for each attack's clip (enemies.json `attackAnim`: its wind-up before the strike and the rest of the clip after it, shortened when the attacks come quicker than the clip; `ATTACK_PAUSE = 0.35 s` after the strike when no clip is known; a 「不停止移动」 attacker never stops; §22.14). Every enemy attack strikes at its clip's damage frame after its swing starts — the first one of a contact too —, and a stun / freeze / sleep / 浮空, hiding, 缴械, 恐惧 or 战栗 (blocked) before that frame cuts the swing: no strike, the next swing starts from its wind-up (0.2.0, `ai.js attackWindup`; PRTS 状态机 / 异常效果 STUNNED; no clip known: no wind-up). FLY enemies ignore ground obstacles (only blockFly units block them) and follow their checkpoint route. A feared enemy runs between random 恐惧可达地块 away from the source (PRTS 诱发移动; `fear.js`); 恐惧 outranks 诱导; the 恐惧 / 诱导 walks re-plan from where the enemy stands after a push or an obstacle change, and the route re-plans when they end (§20.4).
|
||||
- **Enemy AI**: follow the route (checkpoints; WALK paths recomputed on the grid when devices change); when blocked stop & fight (`dmgType 'none'` enemies never attack unless content arms them through `e.profile` — 转译基底's armed forms, §21.4); ranged enemies (`rangeRadius > 0`) attack ops whose 0.25 collider touches their radius (centre distance ≤ `rangeRadius` + 0.25, §3, §20.4): the enemy's own target rule filters the candidates first (`profile.canTarget`: 只攻击地面单位 …), then priority blocker → special priority → highest taunt → **latest deployed** (`aggroSeq`) — PRTS 索敌 "阻挡→特殊优先级→仇恨值→最早出现"; a stealthed ally is attacked only by the enemy it blocks (§19.1) — and not even by that one when its 索敌不受阻挡影响 (自制投石机, `profile.blockFree`: it selects as if unblocked, §25.18) —, and an enemy's area effects — splash, blasts, area skills, zones, jumps — and buff auras skip it unless it blocks that enemy, while 迷彩 does not protect from splash and the other area effects (`targeting.js areaSelectable` / `auraSelectable`, §22.12); an airborne (起飞) ally is never a ground enemy's selection — picks, area damage, zones and statuses skip it, while 无视无法选择 abilities, direct picks, debuff ticks and flying units still reach it (§21.22); unblocked, they stand for each attack's clip (enemies.json `attackAnim`: its wind-up before the strike and the rest of the clip after it, shortened when the attacks come quicker than the clip; `ATTACK_PAUSE = 0.35 s` after the strike when no clip is known; a 「不停止移动」 attacker never stops; §22.14). Every enemy attack strikes at its clip's damage frame after its swing starts — the first one of a contact too —, and a stun / freeze / sleep / 浮空, hiding, 缴械, 恐惧 or 战栗 (blocked) before that frame cuts the swing: no strike, the next swing starts from its wind-up (0.2.0, `ai.js attackWindup`; PRTS 状态机 / 异常效果 STUNNED; no clip known: no wind-up). FLY enemies ignore ground obstacles (only blockFly units block them) and follow their checkpoint route. A feared enemy runs between random 恐惧可达地块 away from the source (PRTS 诱发移动; `fear.js`); 恐惧 outranks 诱导; the 恐惧 / 诱导 walks re-plan from where the enemy stands after a push or an obstacle change, and the route re-plans when they end (§20.4).
|
||||
- **Damage**: phys `max(A − max(0, D×(1−defIgnorePct) − defIgnoreFlat), 0.05·A)`; arts `max(A × (1 − R'/100), 0.05·A)` with `R' = max(0, R×(1−resIgnorePct) − resIgnoreFlat)`; true = A; 元素伤害 ('elemental') `max(A × (1 − 元素抗性/100), 0.05·A)`. Then × `dmgDealtMul` (source) × `dmgTakenMul` & type-specific taken multipliers (target) × `dmg.mul` — 元素伤害 takes 元素脆弱 (`elementalTakenMul`) alone, not `dmgTakenMul` (脆弱 = "受到的物理、法术、真实伤害提升"). Then **限伤**: on a leader (`isBoss` — the 10 bossInfoDict enemyIds and their mirrored copies; never parts, drones or escorts) in a `'boss'` / `'hidden'` battle a hit with `ceil(final) ≥ 300000` is cancelled — no HP or pool loss, no credit, no damage number, no `damaged` / kill (`shared/constants.js BOSS_HIT_LIMIT`, `damage.js leaderHitCancelled`, after every multiplier and the hit-step blocks, before HP shields; `loseHp` too — a part's 传递, but not 胄's drone link, a share of the pool that is no hit (`noHitLimit`, §25.13.4); the client's `MAX_BATTLE_DAMAGE`, §20.12). Then shields absorb; dodge checks for phys/arts. Element damage fills a gauge (1000; enemy leaders 2000) × `elemTakenMul` × max(0.05, 1 − 损伤抵抗/100), 损伤抵抗 = data `epResistance` (PRTS 元素; the 5 % floor of DMG_e, PRTS 游戏数据基础). An element fill on a target with no HP left is refused (damage.js `hasHp`: no burst on a corpse). A full gauge bursts with the side-specific official effects, as **无来源** damage (no damage-dealt multiplier or penetration of the unit that filled the gauge, which keeps the kill and the stats; §19.5) (sim/constants.js `ELEMENT`; operators: 灼燃 1200 arts + RES −20, 神经 stun 10 s then 1000 true, 凋亡 15 s of 阻回 (`noSp`: no SP gain of any kind) + 静默 with −1 SP/s and 100 arts/s, 侵蚀 DEF −100 then 800 phys; enemies: the "·我方" terms). Every burst starts a **爆发冷却** = its duration (灼燃 / 神经 / 侵蚀 10 s — enemies' 侵蚀 8 s — 凋亡 15 s) during which NO element of the unit fills or can be recovered; when it ends every gauge of the unit resets (§18.3).
|
||||
- **Leak**: an enemy reaching its goal is removed, counted as leaked for its field owner (`sourcePlayerId` for unite). LP accounting is done by the match, not the battle.
|
||||
- **Results**: `damageDealt` / a unit's `dmg` count only HP removed from the other side — a unit's own drain or 流失 and friendly damage are the target's `taken` only (§21.12).
|
||||
|
||||
+198
-1
@@ -31,7 +31,10 @@ upgrade, an eliminated player following a player through every round, the boss f
|
||||
prep, the pair together in the boss prep with the official green frames; PRs #189 / #191 reused, not merged; the
|
||||
battle-history and hotkey requests left to the owner) → §25.19; the community reports of 2026-10-06, 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.
|
||||
DoT damage, 伺夜's 狼影 and the 吟游者 trait answered) → §25.16; the community reports of 2026-10-06, stream 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.
|
||||
|
||||
Decisions of the owner: 2026-10-04 — the server stays on plain `node:http` + `ws`, no web framework (§25.1);
|
||||
2026-10-05 — the 补位 plan (§25.3); the 自选编队 rules, the collab operators out of the pool, ISW-A refused (§25.4);
|
||||
@@ -1308,3 +1311,197 @@ the evidence.
|
||||
trait is 生命回复速度, which 禁疗 and 无法被友方治疗 do not stop (§25.6.8): 狼群 440 → 532 and 斥罪 1480 → 1618 HP in 3 s
|
||||
under 魔王 (pinned by `test/content/feedback5-regen.test.js`); 孤立 units stay out (PRTS 孤立). The countdown summons
|
||||
cannot be refilled since §25.16.5.
|
||||
### 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
|
||||
enemies, bosses, waves and movement (items 6, 10, 16.3, 24, 29, 35, 36, 38, 39, 40, 47, 52, 53, 57 of the list). Each was
|
||||
reproduced on the 0.2.0 tree with a script first, then checked against the official data (enemy_database,
|
||||
enemy_handbook_table, activity_table → act2autochess, the level files) and PRTS (备注 included) and the earlier decisions.
|
||||
The real ones are fixed, one commit each with its golden scenarios named; the rest are answered with the evidence.
|
||||
Normative text touched: §5.5 (design/engine.md: 自制投石机's exception to "a stealthed ally is attacked only by the enemy
|
||||
it blocks"); docs/SIM.md (`onOwnBoard`, the 索敌不受阻挡影响 target rule, the silenced 枯朽战士); docs/PLAYING.md (the
|
||||
briefing types' share of the waves).
|
||||
|
||||
#### 25.18.1 「…新约能天使在开了突袭之后蹦到了下方…临时放置溢出的干员和道具的那一栏高台」, 「单人联防时突袭也可以跑到对面的场地上」 (items 40, 16.3): 突袭 lands only on its player's own board — `sim/battle/players.js onOwnBoard`, `content/bonds/addon/battle.js raidTile`
|
||||
|
||||
- **Seen**: in a solo leader round a ranged 突袭 member (新约能天使 with the 转职球 and the 突袭手雷) jumped onto the
|
||||
boss field's 临时整备区 row; in a 联防 with one helper a member jumped onto the right half of the map.
|
||||
- **Cause**: `raidTile` took any tile of the battle rect its position may stand on (grid.canStand). BOSS_RECT holds rows
|
||||
0–5, so the boss field's hand row 0 and 临时整备区 row 1 (tile_achand: high ground, buildable ALL) were landing tiles
|
||||
for a ranged member (reproduced: an enemy on the left telin (1,3) of 战场#01 drew the member onto the hand tile (0,3));
|
||||
UNITE_RECT spans both halves of the 联防 map (cols 0–20) while a lone helper's board is the left half (escaped_single's
|
||||
deploy tiles: cols 3–9), and on a pair field a member jumped onto its partner's half.
|
||||
- **Official**: the bond text 「保留技力立即再部署至一名地面敌人周围」 — a 再部署 goes where its player deploys; the stage data
|
||||
lists each player's deploy tiles per half (data/stages.json `deployTiles`: normal, bossLeft, bossRight).
|
||||
- **Now**: `Battle.onOwnBoard(ps, r, c)` — the board region (rows 9–12, cols 2–10) mapped onto the field as `mapTile`
|
||||
maps the player's pieces (the right-hand helper's +8 columns, the boss rows 2–5, the mirrored right half) — and
|
||||
`raidTile` takes only those tiles; a target only reachable from elsewhere is skipped (the next candidate is tried, else
|
||||
the member stays and the next poll looks again, as before).
|
||||
- [ASSUMED]: none beyond §22.2's landing rule (the official landing tile among the legal ones is not known).
|
||||
- Golden: 8 scenarios, each a member that used to land on the other half (checked with the parent instrumented):
|
||||
boss-boss_2 / 3 / 4 / 5 / 6-pair, hidden-boss_8 / 10-pair (members landing on the partner's half, 1–7 per battle) and
|
||||
the bot match coop2-ABYSS-10-boosted (ai_0's members on the right half of its leader fields). Tests:
|
||||
`test/sim/feedback5-raid-own-board.test.js` (4 cases; each fails on the parent). Docs: docs/SIM.md (`onOwnBoard`).
|
||||
|
||||
#### 25.18.2 「沉默效果没有沉默枯朽战士敌人,枯朽战士敌人被沉默之后死亡依然留下了毒」 (item 10): silenced at its death, 萨卡兹枯朽战士 releases no 污染秽蚀 — `content/enemies/archetypes.js kitPolluted`
|
||||
|
||||
- **Seen**: a silenced 萨卡兹枯朽战士 (组长) still left its poison zone when it died (reproduced: 150 HP in 3 s to its
|
||||
blocker, silenced or not).
|
||||
- **Official**: PRTS 萨卡兹枯朽战士 天赋 「{{特殊机制|死亡爆炸}}(释放半径2.0,持续8s的【污染秽蚀】)」; PRTS 特殊机制 死亡爆炸
|
||||
「如无特殊说明,此能力默认可沉默…若不处于沉默状态,将会…释放」. The client agrees: the battle prefab's PollutedDie
|
||||
ability is a buff of template `projectile_on_killed`, whose ON_OWNER_KILLED checks `CheckAbnormalFlag SILENCED`
|
||||
(unset) before `EmitProjectile` — the same template as 高能源石虫's blast. Its handbook line alone is NORMAL (高能源石虫's is
|
||||
SILENCE), so the rule "`sil` = the handbook's SILENCE lines" (content/enemies.js) missed it. An audit of all 243 enemy
|
||||
prefabs of the local client (every ability's buff templates; those whose ON_OWNER_KILLED checks SILENCED: 11 enemies)
|
||||
found one more NORMAL line of that kind — 刺胄之弹's blast, a part of 假想敌:胄 (not changed, for later: its blast is
|
||||
triggered by its arrival); the other nine are SILENCE lines our kits already silence. 萨卡兹枯朽战车's 秽蚀轰击, also
|
||||
NORMAL, stays unsilenceable (its skill node has `_ignoreSilence` 1).
|
||||
- **Now**: kitPolluted's death ability is `sil`; the silence test of every authored enemy names the two keys as the
|
||||
template exceptions.
|
||||
- [ASSUMED]: none.
|
||||
- Golden: 5 bot matches, each with silenced 枯朽战士 deaths (14–83 per match, counted instrumented): solo-NORMAL-1,
|
||||
coop2-NORMAL-3, coop4-ABYSS-7, coop2-NORMAL-8-serverrun, coop2-NORMAL-14-standins. Tests:
|
||||
`test/content/enemies_bosses.test.js` (the silence rule, the two keys silenced and after a silence ran out; 3 fail on
|
||||
the parent).
|
||||
|
||||
#### 25.18.3 「每局游戏开始展示的敌人类型(折射、飞行等等),实际出现波次在7到9波,而且每个最多三波,其余波次用特异类型填充」 (item 6): already the official schedule — no change
|
||||
|
||||
- **Checked**: `setupMatchWaves` (research 08 §2.1, decoded from the client's `RandomEnemyGenerater`): each of the three
|
||||
briefing types owns 3 of the 15 round slots, SPECIAL (特异) the other 6, shuffled, one type per round. R14 (the leader)
|
||||
and R15 (the hidden core) take slots too, so the 13 normal rounds of 险境 / 绝境 / 终极 hold 7–9 type waves — 400 seeds
|
||||
per mode: 7 in 141 matches, 8 in 192, 9 in 67; per type 1–3 — and every other wave is SPECIAL (solo 标准: 8 normal
|
||||
rounds, 3–7). Exactly what the player describes.
|
||||
- **Official**: act2autochess `specialEnemyRandomTypeDict` (count 3 per random type, SPECIAL −1), constData
|
||||
`maxLevelCnt` 15, `specialEnemyNum` 3, `enemyTypeIdentifierToFillRandom` 1 (SPECIAL).
|
||||
- **Now**: docs/PLAYING.md states it at 确认本局信息 (the report: 「更新日志和机制描述也没写」).
|
||||
- Golden: unchanged. Pinned: `test/sim/feedback5-cb4-pins.test.js` (the 7–9 and the 1–3), `test/match/waves.test.js` (3 of
|
||||
the 15 slots each).
|
||||
|
||||
#### 25.18.4 「敌人新硎提升攻击力的断刃好像无限消耗,实际应当攻击一次消耗一个,具体有几个复核」 (item 53): already fixed in 0.2.0 (§25.6.2, GitHub #107) — no change
|
||||
|
||||
- **Checked**: on v0.1.4 新硎's ATK went 2430 → 3510 → 4590 → 5670 and stayed (a layer per attack, none removed) — the
|
||||
report. On this tree: 4 attacks at 2430 (+80 %), the 4th spends the last 断刃 and ends the bonus, the next swing comes at
|
||||
once at 1350; killed, max(1, 4 − spent) 铁矛头 (沉沙: +70 %, 铜矛头).
|
||||
- **Official**: PRTS 天赋 (4 【断刃】, one spent per successful attack); the client's template `enemy_dead_spawn[sfji]`
|
||||
(battle prefab enemy_1207_sfji_2): ON_OUTPUT_ATK_OR_HEAL — while `cnt` ≥ 1, `cnt` += `cnt_add` (−1) and one blade marker
|
||||
goes; ON_ABILITY_FINISH — `cnt` ≤ 0 ends the ATK buff and switches to mode 1 (无断刃模式); ON_OWNER_KILLED (not 坠落) —
|
||||
summons `cnt` (at least 1).
|
||||
- [ASSUMED]: the client spends a blade per damage output; here every attack spends one, so an attack an operator dodges
|
||||
spends one too.
|
||||
- Golden: unchanged. Pinned: `test/content/enemies_bosses.test.js` (the #107 test).
|
||||
|
||||
#### 25.18.5 「囚犯敌人的解放状态联防时不应继承」 (item 57): already answered (§25.14.1) — no change
|
||||
|
||||
- **Checked**: a leak re-enters 联防 as a new spawn — `planUnite` passes on its key, spawn mods, LP and bounty only, and
|
||||
`buildUniteWave` spawns it — so `prisoner()` starts it confined (the 禁锢 buff, no form) and only its own attacks there
|
||||
free it; the client drops every view when a battle starts. The freed look was 普通 / 老练囚犯's red clip set, drawn from
|
||||
the gate until §25.14.1.
|
||||
- Golden: unchanged. Pinned: `test/sim/feedback5-cb4-pins.test.js` (freed in its own combat, leaked, confined in 联防,
|
||||
freed at its 4th attack there).
|
||||
|
||||
#### 25.18.6 「萨卡兹穿刺手被眩晕或者减速恢复之后移速不会重置(降低),伤害也异常」 (item 36): a stun or 束缚 ends its acceleration; its first hit adds speed × 600 — `content/enemies/special.js kitRush`
|
||||
|
||||
- **Seen**: after a stun it walked on at the speed it had built up (it even kept accelerating while stunned: 1 → 1.5 in a
|
||||
2 s stun); its first hit after a block was one multiplied attack (×(1 + 6 × layers / 25), 2286 at 17 layers), also
|
||||
after a stun that came in between.
|
||||
- **Official**: PRTS 天赋 「每0.1秒检测一次:①若受晕眩/束缚影响,停止加速 ②若未被阻挡,开始加速…每0.5秒尝试获得1层移动速度+50%
|
||||
的增益,最多尝试25次(增益于停止加速时解除…),同时普通攻击附加的Buff会额外造成一次当前移动速度×600的…物理伤害并停止加速」. The
|
||||
battle prefab agrees: listeners every 0.1 s end `dlancer_t[trigger]` on STUNNED (a) or UNMOVABLE (b) and start it when
|
||||
not blocked (c); the trigger stacks a MULTIPLIER move-speed layer every 0.5 s, blocked or not; the FirstAttack buff
|
||||
`dlancer_t_atk` deals `DamageViaAttr` MOVE_SPEED × atk_scale (physical, melee, ignoreForSp) while the trigger exists,
|
||||
then ends it. A slow (减速) is no reset — the report's slow is the official behaviour; it only lowers the speed while it
|
||||
lasts, and so the extra damage.
|
||||
- **Now**: kitRush follows the templates: a 0.1 s listener (晕眩 / 束缚 statuses end the acceleration and drop its layers;
|
||||
not blocked starts it, from the spawn), a layer every 0.5 s up to 25 tries, the extra damage = its current move speed
|
||||
× 600 as a second, non-attack physical instance with no 受击回复, ending the acceleration (so a block's first hit only).
|
||||
Reproduced after the fix: 2 s stun → base speed, a fresh build-up; blocked at 2.375 → 450 + 1500 (2.5 × 600, one more
|
||||
layer before the hit).
|
||||
- [ASSUMED]: 冻结, 沉睡 and 浮空 do not stop it (they set FROZEN / SLEEPING / LEVITATE, not the two flags the listeners
|
||||
read); the client's 0.1 s listener order is folded into one check.
|
||||
- Golden: 6 scenarios, each with 萨卡兹穿刺手 in it: roster-016, standin-04, standin-08, diy-028, diy-124 and the bot match
|
||||
coop2-HARD-4 (160 spawned). Tests: `test/content/enemies_bosses.test.js` (3: the layers and the cap, the resets, the
|
||||
first hit; all fail on the parent).
|
||||
|
||||
#### 25.18.7 「玩家的官方原版反馈:「投石车」敌人如果被蒸汽地板上的干员阻挡会不进行攻击」 (item 24): 自制投石机's 索敌不受阻挡影响 — `targeting.js canTargetAlly / sortAllyTargets`, `ai.js attackTargets`, `content/enemies/special.js` (enemy_10162_mnctpt)
|
||||
|
||||
- **The enemy and the terrain**: 「投石车」 = 自制投石机 (enemy_10162_mnctpt, ranged 4.0, the 悬赏·特异III bounty); the 「蒸汽
|
||||
地板」 = 战场#07 (下半)'s 排气格栅 (tile_smog: an operator on it is 隐匿 to enemy ranged attacks).
|
||||
- **Seen here**: blocked by an operator on the smog, it attacked that operator — every enemy does (the engine's rule: a
|
||||
blocked enemy attacks its blocker whatever its selectability, PRTS 索敌的概念 「…强行无视对方可选性发动攻击」).
|
||||
- **Official**: PRTS 自制投石机 天赋 「…索敌不受阻挡影响,且不会因丢失目标而结束攻击」 — the blocker exception does not apply to
|
||||
it, so a 隐匿 blocker is no target and, with nobody else in its range, it does not attack: the players' report.
|
||||
- **Now**: the catapult's profile is `blockFree` (spawns.js gives every enemy the field): `attackTargets` takes the
|
||||
allies in reach as if it were unblocked, `canTargetAlly` refuses a 隐匿 / 迷彩 blocker to it, `sortAllyTargets` puts no
|
||||
blocker first (仇恨值: taunt, then the latest deployed). Every other enemy keeps attacking a 隐匿 blocker.
|
||||
- [ASSUMED]: none for the rule. Not changed, for later: its stones' splash radius (PRTS 「目标半径1.5范围」, the data's
|
||||
`projectile_range` 0.5 × 3; the kit uses 0.5), the 0.3 s between its three stones, and 「不会因丢失目标而结束攻击」.
|
||||
- Golden: 1 battle — standin-06 (the bounty catapult, blocked by 忍冬, now shot the 斯卡蒂 / 瑕光 pieces by 仇恨值, its
|
||||
blocker no longer first). Tests: `test/sim/feedback5-catapult-smog.test.js` (3: no attack on a hidden blocker alone, another operator
|
||||
instead, every other ranged enemy still attacks its hidden blocker; the first two fail on the parent). Docs:
|
||||
docs/SIM.md.
|
||||
|
||||
#### 25.18.8 「鸭爵策略的悬赏现在有时候会一波出现多只,比如多只鸭子」 (item 35): the official 0–2 swaps per wave — no change
|
||||
|
||||
- **Checked**: 鸭爵's “神秘顾客” (`round_start_all_player_change_enemy_2`: min 0, max 2, from round 5, the late part of the
|
||||
wave — minweight 0.6 / maxweight 0.99) swaps 0–2 ground enemies of each player's wave, each into one of 鸭爵, 高普尼克,
|
||||
流泪小子, 圆仔 at random (bands/meta.js duckReplace, once per player per battle — no second handler). 1000 real waves
|
||||
(`m._normalOpts`, solo and co-op, rounds 5–12): 0 swaps 388, 1 swap 312, 2 swaps 300, never more; the two of a 2-swap
|
||||
wave were the same kind in 81 of 300 (two of one kind in ≈ 1 wave in 12, two ducks in ≈ 1 in 50). A pair leader field holds
|
||||
each player's 0–2 on its own half, and 联防 re-enters every leaker's leaked swaps (both as before).
|
||||
- **Official**: PRTS 卫戍协议:盟约 下半/PRTS盟约记录 鸭爵 备注 「每回合将有0~2名敌人被替换为上述敌人之一」 — two ducks in one
|
||||
wave is the official rule.
|
||||
- Golden: unchanged. Pinned: `test/sim/feedback5-cb4-pins.test.js` (≤ 2 per wave, 0 / 1 / 2 and two of a kind all occur,
|
||||
1 fund each).
|
||||
|
||||
#### 25.18.9 「会移动的关底boss在各个地图的移动路线复核下是否正确」 (item 29): checked on every boss field — no change
|
||||
|
||||
- **Checked**: the leaders that walk are 铳 (boss_2 / 9) and 卢西恩 (boss_5); the 巨型单位 (胄, 管, 昆图斯, 阿利斯泰尔, 萨米的意志)
|
||||
are 自缚 (content/bosses.js SELF_BOUND). Their routes are the level files' (level_act1autochess_h07_02 route 6 and act2
|
||||
h07_05: PATROL_MOVE (3,9) → (2,3) → (5,9), 卢西恩's list four such rounds with a MOVE (5,9) between them), walked with the
|
||||
official SPFA flow field and looped by `patrolLoop` (back to the first leg instead of the goal). On all 8 boss fields
|
||||
of the season, solo and pair, 240 s each: every sample on a walkable tile, the targets in the official order, the pair's
|
||||
mirrored copy on (3,11) → (2,17) → (5,11) (its branch route), 卢西恩 restarting after its 19th checkpoint and never reaching
|
||||
the goal (its lpr 30).
|
||||
- Found, not changed: without the match's `waveId` (tests, tools) `templateOf` infers the template from the route list
|
||||
only and can take another leader's; 卢西恩 then misses its patrol loop and walks to the goal. The match, the server's
|
||||
headless fields and the browser battles always pass it (BattleSpec `waveId`).
|
||||
- Golden: unchanged. Pinned: `test/sim/feedback5-cb4-pins.test.js`.
|
||||
|
||||
#### 25.18.10 「干员野鬃放在红门前两格的时候有概率会把怪顶出地图显示漏怪」 (item 38): not reproduced — no change
|
||||
|
||||
- **Checked**: 野鬃 (elite, S2 夹枪冲锋 kept running) two tiles before either red gate, facing it, on 战场#01–#08 against real
|
||||
waves (912 battles, normal fields; 480 more with the solo leader fields), also on v0.1.4: her pushes (up to 30 a battle)
|
||||
never left a ground enemy on a tile it cannot walk, and every leak happened at its route's end. `Battle.displace`
|
||||
moves a ground enemy only over walkable tiles of the battle rect, so it stops on the gate tile at the field's edge;
|
||||
planLeg then walks it back. What the rule does allow: an enemy she keeps pushing back onto the gate until the time
|
||||
limit is counted as leaked (时间到仍存活的敌人算漏怪), as in the official game. A recording or the map and round would
|
||||
settle what the player saw.
|
||||
- Golden: unchanged. Pinned: `test/sim/feedback5-cb4-pins.test.js` (two real waves, three tiles before the gates).
|
||||
|
||||
#### 25.18.11 「怪物的重量以及干员的推拉力度还是有点不对,比如锏能拉动10重的关底boss」 (item 39): not reproduced — no change
|
||||
|
||||
- **Checked**: a leader (tag boss) is never displaced (`Battle._displaceable`); 锏's S3 pulls with 力度 1 (中力) and, at
|
||||
its end, 2 (较大力): 受力等级 = 力度 − 重量 ≤ −3 moves nothing (PRTS 推与拉), so no weight ≥ 5 enemy moves either. 40 S3
|
||||
casts next to each of the 10 leaders (weights 6–10): never moved; 自在 as a bounty (weight 10) not even by 特大力. The
|
||||
one thing that looks like it: 卢西恩's 不祥幻影 has his model and weight 2, so 锏 does pull it (all the way, 受力等级 0).
|
||||
- Golden: unchanged. Pinned: `test/sim/feedback5-cb4-pins.test.js`.
|
||||
|
||||
#### 25.18.12 「昆图斯占地少最左边和最右边两排,似乎变成3x3了」 (item 47): not reproduced — no change
|
||||
|
||||
- **Checked**: 昆图斯's hit area is PRTS' 「受击判定区域为长4.95宽2.95的长方形,向上偏移1.0」 (tools/build-data.mjs HIT_AREAS):
|
||||
standing on (3,10) it occupies cols 8–12 × rows 3–5 (body.js bodyKeys); an operator whose range reaches only its
|
||||
leftmost column (艾丝黛尔 on (3,7)) attacks it; the Final Assault prep lights the same 15 tiles in red on both boards
|
||||
(headless screenshots of the render demo's Final Assault prep; render/pick.js hitTiles = bodyKeys, pinned by
|
||||
`test/render/feedback3-leader-prep.test.js`). Its model is drawn at the official prefab scale.
|
||||
- Golden: unchanged. Pinned: `test/sim/feedback5-cb4-pins.test.js`.
|
||||
|
||||
#### 25.18.13 「最终boss跟原版相比攻击欲望感觉低了,不怎么打人,复核」 (item 52): every leader attacks at its data interval — no change
|
||||
|
||||
- **Checked**: solo leader fields with eight walls on the board, 150 s: 胄 38 normal attacks (interval 4 s), 昆图斯 43 (3.5 s,
|
||||
two targets each), 阿利斯泰尔 19 (8.2 s), 萨米的意志 25 (6 s) — each at its official interval from its first target on —,
|
||||
their skills at their cooldowns; v0.1.4 gives the same counts (only the first strike now comes at the damage frame,
|
||||
§25.7.2). 铳 opens at the PRTS minimum attack speed 20 (22.5 s) and gains +80 per attack on the same target (5 times),
|
||||
so a fight that keeps switching its target sees few of its attacks; 管's normal attacks strike its 余音, not operators;
|
||||
卢西恩 attacks only its blocker and blinks past it. A leader and a situation from the reporter would show what differs.
|
||||
- Golden: unchanged. Pinned: `test/sim/feedback5-cb4-pins.test.js` (the four interval leaders at ≥ max − 1 attacks).
|
||||
|
||||
+5
-2
@@ -718,10 +718,13 @@ export function attackWindup(e) {
|
||||
return a && a.dur > 0 ? clipHit(a) / clipSpeed(e, a) : 0;
|
||||
}
|
||||
|
||||
/** The allies `e` could hit now: its blocker (and, with a range, the others in reach), passing its own target rule. */
|
||||
/**
|
||||
* The allies `e` could hit now: its blocker (and, with a range, the others in reach), passing its own target rule. An
|
||||
* enemy whose 索敌不受阻挡影响 (profile `blockFree`: 自制投石机) selects as if unblocked: the allies in reach it may target.
|
||||
*/
|
||||
function attackTargets(b, e, radius, reach, own) {
|
||||
let targets = [];
|
||||
if (e.blockedBy) {
|
||||
if (e.blockedBy && !(radius > 0 && e.profile && e.profile.blockFree)) {
|
||||
const bl = e.blockedBy;
|
||||
if (radius > 0) {
|
||||
targets = b.alliesInRadius(e.x, e.y, reach, null).filter((a) => a === bl || canTargetAlly(e, a, true));
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// Installed on Battle.prototype by server/sim/Battle.js (a method container: never instantiated; `this` is the battle).
|
||||
|
||||
import { COLS, BOSS_ROW_OFFSET } from '../constants.js';
|
||||
import { GEO } from '../../../shared/constants.js';
|
||||
import { Unit } from '../units.js';
|
||||
import { normDir, mirrorDir } from '../dir.js';
|
||||
import { SkillRuntime } from '../skills.js';
|
||||
@@ -70,6 +71,29 @@ export class BattlePlayers {
|
||||
/** Board → field tile for a player (see header). */
|
||||
mapTile(ps, row, col, abs = false) {
|
||||
if (abs || ps.coords === 'field') return [row, col];
|
||||
return this._boardTile(ps, row, col);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether field tile (r, c) lies on player `ps`'s own board: the board region GEO.FIELD (rows 9–12, cols 2–10, the
|
||||
* 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).
|
||||
*/
|
||||
onOwnBoard(ps, r, c) {
|
||||
if (!ps) return false;
|
||||
let keys = ps._boardKeys;
|
||||
if (!keys) {
|
||||
keys = ps._boardKeys = new Set();
|
||||
for (let br = GEO.FIELD.r0; br <= GEO.FIELD.r1; br++) {
|
||||
for (let bc = GEO.FIELD.c0; bc <= GEO.FIELD.c1; bc++) { const [fr, fc] = this._boardTile(ps, br, bc); keys.add(fr * COLS + fc); }
|
||||
}
|
||||
}
|
||||
return keys.has(r * COLS + c);
|
||||
}
|
||||
|
||||
_boardTile(ps, row, col) {
|
||||
const bossLike = this.kind === 'boss' || this.kind === 'hidden';
|
||||
let r = row;
|
||||
if (ps.rowOffset != null) r = row + ps.rowOffset;
|
||||
|
||||
@@ -134,8 +134,9 @@ export class BattleSpawns {
|
||||
e.atkStandUntil = -Infinity; // standing for its attack clip (ai.js attackStand)
|
||||
e.swing = false; // a normal attack swung, its damage frame not reached yet (ai.js enemyAttack)
|
||||
// every enemy profile starts with the same fields (stable object shapes keep the hot loop's property reads fast);
|
||||
// `dmgType` null = the data's (content may arm a data-unarmed enemy: ai.js enemyAttack)
|
||||
e.profile = { noAttack: def.dmgType === 'none', maxTargets: 1, atkScale: 1, dmgType: null };
|
||||
// `dmgType` null = the data's (content may arm a data-unarmed enemy: ai.js enemyAttack); `blockFree` = its 索敌不受阻挡
|
||||
// 影响 (content: 自制投石机 — targeting.js canTargetAlly / sortAllyTargets, ai.js attackTargets)
|
||||
e.profile = { noAttack: def.dmgType === 'none', maxTargets: 1, atkScale: 1, dmgType: null, blockFree: false };
|
||||
e.route = { legs: route ? compileRoute(route, this.rect) : [], legIdx: 0, pts: null, ptIdx: 0, suffix: null, version: -1, waitLeft: null };
|
||||
if (!e.route.legs.length) {
|
||||
const end = this.grid.specialTiles('end')[0];
|
||||
|
||||
@@ -33,7 +33,9 @@
|
||||
// 助力 deputShip all operators DEF +(base + per·L), redeploy time ×(1 + respawn_time)
|
||||
// 突袭 raidShip member idle ≥ no_attack_duration s (or skill ready — a passive skill that is on counts, GitHub
|
||||
// #49, and so does a deploy-timed skill while it runs, #109) with no enemy in range → "保留技力立即再部署"
|
||||
// next to the most advanced ground enemy it can reach: on a free tile its position may be deployed
|
||||
// next to the most advanced ground enemy it can reach: on a free tile of its own board (Battle.onOwnBoard:
|
||||
// never a boss field's hand / 临时整备区 rows, never the other half of a 联防 or boss field — community
|
||||
// reports of 2026-10-06, items 40 and 16.3) its position may be deployed
|
||||
// on from which its range covers that enemy (GitHub issue #51 [ASSUMED]: the first of the 8 most
|
||||
// advanced that has such a tile; none → it stays and the next poll looks again, never a jump that
|
||||
// hits nothing) — for a melee member that blocks, a tile where its block applies first (ground
|
||||
@@ -269,7 +271,11 @@ function raidReach(u) {
|
||||
/**
|
||||
* Landing tile [row, col] of a jump to enemy `e`, or null: a tile from which the member's range (`reach`, raidReach)
|
||||
* covers the enemy's body (a huge enemy: any tile it occupies — body.js), within RAID_SEARCH tiles (Chebyshev) of the
|
||||
* enemy, inside the field rect, that the member's position may be deployed on (grid.canStand: never the 深水区 —
|
||||
* enemy, inside the field rect and on the member's own board (Battle.onOwnBoard — "再部署" goes where its player deploys:
|
||||
* never a boss field's hand row 0 or 临时整备区 row 1, both inside BOSS_RECT and buildable high ground, nor the half of the
|
||||
* 联防 or boss field that is not its player's; community reports of 2026-10-06, items 40 and 16.3: a ranged member landed
|
||||
* on the 临时整备区 row of a solo leader round, and on the right half of the one-helper 联防 map), that the member's
|
||||
* position may be deployed on (grid.canStand: never the 深水区 —
|
||||
* player report #3 after 0.1.0 —, and for a melee member low ground only, never a 高台: GitHub #148) and that is free
|
||||
* (Battle.isReservedTile: no living unit, no knocked-out operator's body — player report F5 —, no waiting piece's tile).
|
||||
* A melee member that blocks takes a tile where its block applies first — ground units pass it (not a 围墙 / 围栏 tile,
|
||||
@@ -293,7 +299,7 @@ function raidTile(battle, u, e, reach) {
|
||||
for (let i = 0; i < reach.length; i += 2) {
|
||||
const r = br - reach[i], c = bc - reach[i + 1], dr = r - er, dc = c - ec;
|
||||
if (Math.abs(dr) > RAID_SEARCH || Math.abs(dc) > RAID_SEARCH) continue;
|
||||
if (!battle.grid.inRect(r, c) || !battle.grid.canStand(r, c, { ranged }) || battle.isReservedTile(r, c)) continue;
|
||||
if (!battle.grid.inRect(r, c) || !battle.onOwnBoard(u.player, r, c) || !battle.grid.canStand(r, c, { ranged }) || battle.isReservedTile(r, c)) continue;
|
||||
const t = r * COLS + c;
|
||||
const p = path && battle.grid.tile(r, c).pass === 'ALL' && (path.has(t) || body.includes(t)) ? 0 : 1; // its block applies
|
||||
const d = Math.max(Math.abs(dr), Math.abs(dc)) + 0.01 * (Math.abs(dr) + Math.abs(dc));
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
// there: an enemy gains 1 layer — 2 at 重量 ≥ heavyWeight (the device's `value`, 3) — of ASPD aspdPerStack
|
||||
// (fractions are ×100 ASPD) and move speed × (1 + moveMulPerStack × layers), an operator 1 layer of the
|
||||
// ASPD part only; at most maxStacks layers; cleared on leaving
|
||||
// 烟雾 g operators on it cannot be targeted by enemy ranged attacks (stealth flag: blocked enemies still hit them)
|
||||
// 烟雾 g operators on it cannot be targeted by enemy ranged attacks (stealth flag: blocked enemies still hit them —
|
||||
// not 自制投石机, whose 索敌不受阻挡影响: blocked by one with nobody else in range it does not attack)
|
||||
// 深水 d ground enemies on it: sea_drown[enemy].damage dmg/s (无来源 true 持续伤害, not 环境伤害: tags dot /
|
||||
// periodic / deepsea), ASPD attack_speed (×100), move × move_speed
|
||||
// 活性源石 i a unit on it (allies and ground enemies) gets a timed effect: damage true dmg/s, ATK + atk, ASPD +
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
// hidden from later 'kill' handlers) · death(c,…) · status(c,…) (statusApplied on e) · burst(c,…) (elementBurst on e)
|
||||
// · tick(b,e,a,dt) every `iv` s (every tick when iv is 0) · skill: `cd`/`left`(=icd)/`cond`/`fire` (cooldown runs
|
||||
// continuously; fires when ready, the enemy can act and `cond` holds). `sil: true` = the ability's handbook line
|
||||
// is flagged SILENCE (沉默 disables it: exactly the data's `format: "SILENCE"` lines); stun / freeze / sleep block
|
||||
// is flagged SILENCE (沉默 disables it: exactly the data's `format: "SILENCE"` lines — and 萨卡兹枯朽战士 / 组长's
|
||||
// 死亡爆炸, a NORMAL line whose client template checks 沉默: archetypes.js kitPolluted); stun / freeze / sleep block
|
||||
// skills. Enemy SP skills ("数次攻击后…"): SP +1 per attack, the (spCost+1)-th attack is the skill attack (official
|
||||
// 粉碎攻坚手 text: spCost 2 = "攻击2次后,下一次攻击").
|
||||
// Shared mechanics: reborn() — "首次被击倒后重生 / 第二形态" (the first KO is hidden from kill credit and bounty; a
|
||||
|
||||
@@ -630,7 +630,17 @@ const kitSelfFear = (ab) => [selfFear(ab)];
|
||||
* after a block ends, the warrior's own block that the knock-out releases included (Battle._stealthSwitch). */
|
||||
const kitEmber = (ab) => [husk({ hits: T(ab, 'Revive[Trigger].prop_max_hp'), delay: T(ab, 'Revive[Trigger].interval') })];
|
||||
|
||||
/**
|
||||
* 萨卡兹枯朽战士 / 组长 · death: 【污染秽蚀】 (PRTS 天赋 "{{特殊机制|死亡爆炸}}(释放半径2.0,持续8s的【污染秽蚀】)"). Silenced at its
|
||||
* death it releases nothing: PRTS 特殊机制 死亡爆炸 "如无特殊说明,此能力默认可沉默…若不处于沉默状态,将会…释放", and the
|
||||
* client agrees — its PollutedDie ability is a buff of template `projectile_on_killed` (battle prefab
|
||||
* enemy_1267_nhpbr / _2), whose ON_OWNER_KILLED first checks `CheckAbnormalFlag SILENCED` (unset) before it emits the
|
||||
* pollution projectile — the template of 高能源石虫's SILENCE-flagged blast too. Its handbook line alone is NORMAL, the one
|
||||
* exception to the handbook rule of content/enemies.js (community report of 2026-10-06, item 10: until 0.2.0 a
|
||||
* silenced one still poisoned its blockers).
|
||||
*/
|
||||
const kitPolluted = (ab) => [{
|
||||
sil: true,
|
||||
death(c, b, e) {
|
||||
if (c.reason !== 'killed') return;
|
||||
pollution(b, e, e.x, e.y, T(ab, 'PollutedDie.projectile_range') ?? 1, T(ab, 'PollutedDie.projectile_life_time') ?? 0,
|
||||
|
||||
@@ -126,23 +126,49 @@ function kitParrot(ab) {
|
||||
}];
|
||||
}
|
||||
|
||||
/**
|
||||
* 萨卡兹穿刺手 (PRTS 天赋; the battle prefab's Rush / FirstAttack abilities — templates dlancer_t_listener[a] / [b] / [c],
|
||||
* dlancer_t[trigger], dlancer_t_atk): every RUSH_LISTEN (0.1) s — 晕眩 (STUNNED) or 束缚 (UNMOVABLE) ends the acceleration
|
||||
* and its speed layers with it; not blocked and not accelerating starts it. While it accelerates, every
|
||||
* `rush.dlancer_t[trigger].interval` (0.5) s — the first one 0.5 s after the start — one more layer of move speed
|
||||
* +`move_speed` (50 %, MULTIPLIER, the layers add up), at most `trig_cnt` (25) tries — blocked or not, frozen, asleep or
|
||||
* slowed or not (only the two flags stop it). Every normal attack carries dlancer_t_atk: while it accelerates, the hit
|
||||
* adds 当前移动速度 × `firstattack.atk_scale` (600) physical damage — a second instance, melee, no 受击回复 (ignoreForSp) —
|
||||
* and ends the acceleration, so once blocked only its first hit has it. Until 0.2.0 it kept accelerating through a stun
|
||||
* and kept the speed after it, and the first hit after a block multiplied the attack instead (×(1 + 6 × layers / 25)),
|
||||
* a stun in between included (community report of 2026-10-06, item 36).
|
||||
*/
|
||||
const RUSH_LISTEN = 0.1;
|
||||
|
||||
function kitRush(ab) {
|
||||
const ms = T(ab, 'rush.dlancer_t[trigger].move_speed') ?? 0, iv = T(ab, 'rush.dlancer_t[trigger].interval') ?? 0.5;
|
||||
const max = T(ab, 'rush.dlancer_t[trigger].trig_cnt') ?? 0, first = T(ab, 'firstattack.atk_scale') ?? 0;
|
||||
const max = T(ab, 'rush.dlancer_t[trigger].trig_cnt') ?? 0, scale = T(ab, 'firstattack.atk_scale') ?? 0;
|
||||
// 晕眩 / 束缚 only (the client's STUNNED / UNMOVABLE flags: not 冻结, 沉睡 or 浮空, which hold flags.stun here too)
|
||||
const held = (e) => e.buffs.some((x) => x.status === 'stun' || x.status === 'bind');
|
||||
const stop = (b, e, a) => { a.on = false; a.n = 0; b.removeBuff(e, 'ab:rush'); };
|
||||
return [{
|
||||
iv,
|
||||
spawn(b, e, a) { a.n = 0; },
|
||||
tick(b, e, a) {
|
||||
if (!e.moving || e.blockedBy || a.n >= max) return;
|
||||
a.n++;
|
||||
b.addBuff(e, { key: 'ab:rush', mods: { moveMul: 1 + ms * a.n }, persist: true });
|
||||
iv: RUSH_LISTEN,
|
||||
// the listeners first look at once (waitFirstTriggerInterval 0): a walker spawned unblocked starts at t = 0
|
||||
spawn(b, e, a) { a.on = !e.blockedBy && !held(e); a.n = 0; a.tries = 0; a.acc = 0; },
|
||||
tick(b, e, a, dt) {
|
||||
if (held(e)) { if (a.on) stop(b, e, a); return; }
|
||||
if (!a.on) {
|
||||
if (!e.blockedBy) { a.on = true; a.tries = 0; a.acc = 0; }
|
||||
return;
|
||||
}
|
||||
if (a.tries >= max || !(iv > 0)) return;
|
||||
a.acc += dt;
|
||||
let grew = false;
|
||||
while (a.acc >= iv - 1e-9 && a.tries < max) { a.acc -= iv; a.tries++; a.n++; grew = true; }
|
||||
if (grew) b.addBuff(e, { key: 'ab:rush', mods: { moveMul: 1 + ms * a.n }, persist: true });
|
||||
},
|
||||
blocked(c, b, e, a) { a.charge = a.n; },
|
||||
hitOut(c, b, e, a) {
|
||||
if (!c.dmg.isAttack || !(a.charge > 0) || !(max > 0)) return;
|
||||
c.dmg.amount *= 1 + (first / 100) * (a.charge / max); // 被阻挡后的首次攻击: extra damage from the built-up speed
|
||||
dealt(c, b, e, a) {
|
||||
if (!a.on) return;
|
||||
const t = c.target;
|
||||
const amount = e.s.moveSpeed * scale;
|
||||
stop(b, e, a);
|
||||
if (t && t.alive && amount > 0) b.dealDamage(e, t, { amount, type: 'phys', canDodge: false, isSkill: true, noSp: true, tags: ['enemyAbility', 'rush'] });
|
||||
},
|
||||
attack(c, b, e, a) { if (a.charge > 0) { a.charge = 0; a.n = 0; b.removeBuff(e, 'ab:rush'); } },
|
||||
}];
|
||||
}
|
||||
|
||||
@@ -378,7 +404,11 @@ export const SPECIAL_KITS = Object.freeze({
|
||||
b.fx('explode', { x: e.x, y: e.y, r, kind: 'heal' });
|
||||
for (const o of b.enemiesInRadius(e.x, e.y, r)) if (o !== e) b.heal(e, o, amt);
|
||||
} }],
|
||||
enemy_10162_mnctpt: (ab) => [{ // 自制投石机 · 3-hit attacks with small splash
|
||||
enemy_10162_mnctpt: (ab) => [{ // 自制投石机 · 3-hit attacks with small splash; 索敌不受阻挡影响
|
||||
// PRTS 天赋 「索敌不受阻挡影响,且不会因丢失目标而结束攻击」: its target selection ignores its block — a 隐匿 blocker (an
|
||||
// operator on the 排气格栅) is no target, so with nobody else in range it does not attack (the official game, community
|
||||
// report of 2026-10-06, item 24); it picks by 仇恨值, not its blocker first
|
||||
spawn(b, e) { e.profile.blockFree = true; },
|
||||
dealt(c, b, e) {
|
||||
const n = T(ab, 'Attack.attack@times') ?? 1, r = T(ab, 'Attack.attack@projectile_range') ?? 0;
|
||||
const t = c.target;
|
||||
|
||||
@@ -99,13 +99,15 @@ export function canTargetEnemy(attacker, e, profile) {
|
||||
* PRTS 异常效果 gives both anomalies the note "与'阻挡时解除'没有直接关系" — for this target selection (an attack, a skill
|
||||
* pick, a cast condition, a normal attack on every ally in range: PRTS 选择器 "所有触发选择器通常不无视迷彩"); an area
|
||||
* effect selects with areaSelectable / auraSelectable, which do not check 迷彩. An airborne ally (起飞, flag `liftoff`) is
|
||||
* never a target of a ground enemy (evadesGround).
|
||||
* never a target of a ground enemy (evadesGround). An enemy whose 索敌不受阻挡影响 (profile `blockFree`: 自制投石机, PRTS 天赋)
|
||||
* has no blocker exception: a 隐匿 / 迷彩 ally that blocks it is no target either — so, blocked by an operator on the
|
||||
* 排气格栅 with nobody else in range, it does not attack (the official game, community report of 2026-10-06, item 24).
|
||||
*/
|
||||
export function canTargetAlly(e, a, ranged) {
|
||||
if (!a.alive || !a.deployed || a.hidden || a.kind === 'device') return false;
|
||||
const f = a.s.flags;
|
||||
if (f.untargetable || f.sleep) return false;
|
||||
if (ranged && (f.stealth || f.camou) && e.blockedBy !== a) return false;
|
||||
if (ranged && (f.stealth || f.camou) && (e.blockedBy !== a || (e.profile && e.profile.blockFree))) return false;
|
||||
if (f.liftoff && evadesGround(e, a)) return false;
|
||||
return true;
|
||||
}
|
||||
@@ -221,8 +223,9 @@ export function sortEnemyTargets(battle, attacker, cands, priority) {
|
||||
*/
|
||||
export function sortAllyTargets(enemy, cands) {
|
||||
if (cands.length <= 1) return cands;
|
||||
const bl = enemy.profile && enemy.profile.blockFree ? null : enemy.blockedBy; // 索敌不受阻挡影响: no blocker first
|
||||
cands.sort((a, b) => {
|
||||
const ba = enemy.blockedBy === a ? 0 : 1, bb = enemy.blockedBy === b ? 0 : 1;
|
||||
const ba = bl === a ? 0 : 1, bb = bl === b ? 0 : 1;
|
||||
return ba - bb || aggroCmp(a, b);
|
||||
});
|
||||
return cands;
|
||||
|
||||
@@ -70,12 +70,17 @@ test('stats-only enemies attach no ability and fight with their data stats', ()
|
||||
}
|
||||
});
|
||||
|
||||
test('沉默: exactly the abilities whose handbook line is SILENCE-flagged can be silenced (every authored enemy)', () => {
|
||||
// Abilities the client makes silenceable although their handbook line is NORMAL (the battle prefab's buff template checks
|
||||
// SILENCED): 萨卡兹枯朽战士 / 组长's PollutedDie = template projectile_on_killed, the 死亡爆炸 template of 高能源石虫's
|
||||
// SILENCE-flagged blast too (community report of 2026-10-06, item 10; DESIGN §25.18.2)
|
||||
const SILENCE_BY_TEMPLATE = new Set(['enemy_1267_nhpbr', 'enemy_1267_nhpbr_2']);
|
||||
|
||||
test('沉默: exactly the abilities whose handbook line is SILENCE-flagged can be silenced (every authored enemy), plus the ones whose client template checks it', () => {
|
||||
const h = arena();
|
||||
h.step();
|
||||
for (const key of [...Object.keys(KITS), ...Object.keys(BOSS_KITS)]) {
|
||||
const e = put(h, key, [10, 7]);
|
||||
const data = E[key].abilities.some((a) => a.format === 'SILENCE');
|
||||
const data = E[key].abilities.some((a) => a.format === 'SILENCE') || SILENCE_BY_TEMPLATE.has(key);
|
||||
const kit = !!(e.mem.ab && e.mem.ab.list.some((a) => a && (a.sil || a.silAware)));
|
||||
assert.equal(kit, data, `${nm(key)}: ${E[key].abilities.map((a) => `[${a.format}]${a.text}`).join(' / ')}`);
|
||||
h.b.kill(e, null);
|
||||
@@ -674,6 +679,30 @@ for (const key of ['enemy_1267_nhpbr', 'enemy_1267_nhpbr_2']) {
|
||||
h.run(3.05);
|
||||
approx(h.unit('t_wall').stats.taken, 3 * tb(key, 'PollutedDie.polluted_damage_low'));
|
||||
});
|
||||
|
||||
// PRTS 特殊机制 死亡爆炸 "默认可沉默…若不处于沉默状态,将会…释放"; client template projectile_on_killed: CheckAbnormalFlag
|
||||
// SILENCED (unset) before EmitProjectile (community report of 2026-10-06, item 10: a silenced one still poisoned)
|
||||
test(`${nm(key)}: silenced when it dies, it releases no 污染秽蚀; a silence that ran out does not stop it`, () => {
|
||||
const h = arena({ units: [{ chessId: 't_wall', row: 10, col: 6 }] });
|
||||
h.step();
|
||||
const e = put(h, key, [10, 7]);
|
||||
h.b.applyStatus(e, 'silence', { duration: 30 });
|
||||
h.step();
|
||||
assert.ok(e.s.flags.silence);
|
||||
killed(h, e, null);
|
||||
h.run(3.05);
|
||||
assert.equal(h.unit('t_wall').stats.taken, 0);
|
||||
assert.equal(h.eventsOf('fx').filter((x) => x[1] === 'zone' && x[4] && x[4].kind === 'pollution').length, 0, 'no zone');
|
||||
const h2 = arena({ units: [{ chessId: 't_wall', row: 10, col: 6 }] });
|
||||
h2.step();
|
||||
const e2 = put(h2, key, [10, 7]);
|
||||
h2.b.applyStatus(e2, 'silence', { duration: 1 });
|
||||
h2.run(1.5);
|
||||
assert.ok(!e2.s.flags.silence);
|
||||
killed(h2, e2, null);
|
||||
h2.run(3.05);
|
||||
approx(h2.unit('t_wall').stats.taken, 3 * tb(key, 'PollutedDie.polluted_damage_low'));
|
||||
});
|
||||
}
|
||||
|
||||
for (const key of ['enemy_1270_nhstlk', 'enemy_1270_nhstlk_2']) {
|
||||
@@ -1042,16 +1071,68 @@ for (const key of ['enemy_1116_liprr', 'enemy_1116_liprr_2', 'enemy_1118_lidbox_
|
||||
});
|
||||
}
|
||||
|
||||
test(`${nm('enemy_1072_dlancer')}: accelerates while walking; the first hit after being blocked scales with the build-up`, () => {
|
||||
const h = arena({ units: [{ chessId: 't_wall', row: 9, col: 3 }], captureNoisy: true, hooks: ['damaged'] });
|
||||
// PRTS 天赋 + the client's templates dlancer_t_listener[a/b/c], dlancer_t[trigger], dlancer_t_atk (DESIGN §25.18): every
|
||||
// 0.1 s 晕眩 / 束缚 end the acceleration (its layers with it), not blocked starts it; a layer of move speed +50 % every
|
||||
// 0.5 s, at most 25 tries, blocked or not; a hit while it accelerates adds 当前移动速度 × 600 phys (its own instance) and
|
||||
// ends it (community report of 2026-10-06, item 36: until 0.2.0 a stun kept the speed, and the hit was multiplied)
|
||||
const DL = 'enemy_1072_dlancer';
|
||||
const dlBase = () => E[DL].stats.moveSpeed;
|
||||
const dlMul = (n) => 1 + tb(DL, 'rush.dlancer_t[trigger].move_speed') * n;
|
||||
const DL_ROUTE = { motion: 'WALK', start: [9, 18], end: [9, 2], checkpoints: [] };
|
||||
test(`${nm(DL)}: a layer of move speed +${tb(DL, 'rush.dlancer_t[trigger].move_speed') * 100} % every ${tb(DL, 'rush.dlancer_t[trigger].interval')} s while it walks, at most ${tb(DL, 'rush.dlancer_t[trigger].trig_cnt')}`, () => {
|
||||
const h = arena();
|
||||
h.step();
|
||||
const e = put(h, 'enemy_1072_dlancer', [9, 10], { move: true });
|
||||
h.run(3);
|
||||
assert.ok(e.s.moveSpeed > E.enemy_1072_dlancer.stats.moveSpeed * 2);
|
||||
h.runUntil(() => e.stats.attacks >= 2, 120);
|
||||
const hits = h.hooksOf('damaged').filter((c) => c.source === e && c.dmg.isAttack).map((c) => c.amount);
|
||||
assert.ok(hits[0] > hits[1] * 1.5, `${hits[0]} vs ${hits[1]}`);
|
||||
approx(hits[1], e.s.atk);
|
||||
const e = h.spawn(DL, { route: DL_ROUTE });
|
||||
h.run(0.45);
|
||||
approx(e.s.moveSpeed, dlBase(), 1e-9, 'the first layer 0.5 s after the start');
|
||||
h.run(2.6);
|
||||
approx(e.s.moveSpeed, dlBase() * dlMul(6), 1e-9, '6 layers after 3 s');
|
||||
// the cap: a pinned one (speed ×0, never blocked) keeps trying — 25 tries, then the layers stay
|
||||
const p = put(h, DL, [11, 12]);
|
||||
h.run(14);
|
||||
const max = tb(DL, 'rush.dlancer_t[trigger].trig_cnt');
|
||||
assert.equal(p.mem.ab.list[0].n, max);
|
||||
approx(p.findBuff('ab:rush').mods.moveMul, dlMul(max), 1e-9, 'capped at 25 layers');
|
||||
});
|
||||
|
||||
test(`${nm(DL)}: a stun or a 束缚 ends the acceleration — its speed back to the base, building up again only afterwards; a slow, a freeze or a sleep does not`, () => {
|
||||
for (const [status, value, resets] of [['stun', undefined, true], ['bind', undefined, true], ['slow', 0.5, false], ['freeze', undefined, false], ['sleep', undefined, false]]) {
|
||||
const h = arena();
|
||||
h.step();
|
||||
const e = h.spawn(DL, { route: DL_ROUTE });
|
||||
h.run(3.05);
|
||||
approx(e.s.moveSpeed, dlBase() * dlMul(6), 1e-9, status);
|
||||
h.b.applyStatus(e, status, { duration: 2, value });
|
||||
h.run(2.2);
|
||||
if (resets) {
|
||||
approx(e.s.moveSpeed, dlBase(), 1e-9, `${status}: reset`);
|
||||
h.run(1.05);
|
||||
approx(e.s.moveSpeed, dlBase() * dlMul(2), 1e-9, `${status}: a fresh build-up`);
|
||||
} else assert.ok(e.s.moveSpeed > dlBase() * dlMul(6) - 1e-9, `${status}: kept (${e.s.moveSpeed})`);
|
||||
}
|
||||
});
|
||||
|
||||
test(`${nm(DL)}: blocked, its first hit adds 当前移动速度 × ${tb(DL, 'firstattack.atk_scale')} physical damage (a second instance) and ends the acceleration; a stun between the block and the hit takes it away`, () => {
|
||||
const hitsOf = (stunAtBlock) => {
|
||||
const h = arena({ units: [{ chessId: 't_wall', row: 9, col: 4 }], captureNoisy: true, hooks: ['damaged'] });
|
||||
h.step();
|
||||
const e = h.spawn(DL, { route: DL_ROUTE });
|
||||
let speedAtHit = null;
|
||||
h.b.on('damaged', (c) => { if (c.source === e && c.dmg.isAttack && speedAtHit === null) speedAtHit = e.s.moveSpeed; }, { priority: 100 });
|
||||
assert.ok(h.runUntil(() => e.blockedBy, 120), 'blocked');
|
||||
if (stunAtBlock) h.b.applyStatus(e, 'stun', { duration: 1 });
|
||||
assert.ok(h.runUntil(() => e.stats.attacks >= 2, 60));
|
||||
const own = h.hooksOf('damaged').filter((c) => c.source === e);
|
||||
return { e, speedAtHit, attacks: own.filter((c) => c.dmg.isAttack).map((c) => c.amount), extra: own.filter((c) => !c.dmg.isAttack).map((c) => c.amount) };
|
||||
};
|
||||
const r = hitsOf(false);
|
||||
assert.ok(r.speedAtHit > dlBase() * 4, `built up: ${r.speedAtHit}`);
|
||||
assert.deepEqual(r.attacks.map((a) => Math.round(a)), [r.e.s.atk, r.e.s.atk], 'the attacks themselves are plain');
|
||||
assert.equal(r.extra.length, 1, 'one extra instance, on the first hit only');
|
||||
approx(r.extra[0], r.speedAtHit * tb(DL, 'firstattack.atk_scale'), 1e-6, 'speed × 600 (DEF 0)');
|
||||
approx(r.e.s.moveSpeed, dlBase(), 1e-9, 'the hit ended the acceleration');
|
||||
const s = hitsOf(true);
|
||||
assert.deepEqual(s.extra, [], 'stunned after the block: no extra damage');
|
||||
});
|
||||
|
||||
test(`${nm('enemy_1320_wdrrl_2')}: only blockers with block ≥3; first attack splashes ATK×${tb('enemy_1320_wdrrl_2', 'AOEAttack.atk_scale')} around the target`, () => {
|
||||
|
||||
+41
-41
@@ -1115,35 +1115,35 @@
|
||||
"round": 13,
|
||||
"seed": 2789905475,
|
||||
"waveId": "act1autochess_h06",
|
||||
"time": 213.13,
|
||||
"ticks": 6394,
|
||||
"time": 209.47,
|
||||
"ticks": 6284,
|
||||
"reason": "cleared",
|
||||
"killed": 23,
|
||||
"killed": 24,
|
||||
"total": 147,
|
||||
"unspawned": 0,
|
||||
"bossHpLeft": null,
|
||||
"rngDraws": 267,
|
||||
"rngDraws": 334,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {"p1":{"killed":23,"total":147,"perfect":false,"leaks":124,"leaksUncounted":0,"coins":0,"dmg":1691383,"bossDmg":0,"heal":0,"deaths":21,"layerGains":{}}},
|
||||
"players": {"p1":{"killed":24,"total":147,"perfect":false,"leaks":123,"leaksUncounted":0,"coins":0,"dmg":1441375,"bossDmg":0,"heal":0,"deaths":21,"layerGains":{}}},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_6_diy1_b",0,"uniequip_002_narant",2331,1,162,4,550355,2331,0,96,2],
|
||||
["p1",2,"op","chess_char_6_diy2_b",1,"uniequip_002_narant",2331,1,170,5,169611,4662,0,45,2],
|
||||
["p1",3,"op","chess_char_6_diy1_b",2,"uniequip_002_narant",0,0,123,1,161168,4662,0,46,2],
|
||||
["p1",4,"op","chess_char_6_diy2_b",0,"uniequip_003_narant",0,0,140,1,176278,5262,0,36,2],
|
||||
["p1",5,"op","chess_char_6_diy1_b",1,"uniequip_003_narant",0,0,152,8,468412,5262,0,89,2],
|
||||
["p1",6,"op","chess_char_6_diy2_b",2,"uniequip_003_narant",2631,1,171,4,121589,2631,0,28,1],
|
||||
["p1",7,"op","chess_char_5_diy1_a",0,null,0,0,78,0,2832,2594,0,6,0],
|
||||
["p1",8,"op","chess_char_5_diy2_a",1,null,0,0,94,0,6919,2594,0,15,1],
|
||||
["p1",9,"op","chess_char_5_diy1_a",2,null,0,0,84,0,4842,2594,0,9,0],
|
||||
["p1",10,"op","chess_char_5_diy2_b",0,"none",0,0,83,0,3441,3080,0,7,0],
|
||||
["p1",11,"op","chess_char_5_diy1_b",1,"none",0,0,4,0,18086,1540,0,27,1],
|
||||
["p1",12,"op","chess_char_5_diy2_b",2,"none",0,0,89,0,7850,3080,0,13,0]
|
||||
["p1",1,"op","chess_char_6_diy1_b",0,"uniequip_002_narant",0,0,113,4,225132,4662,0,45,2],
|
||||
["p1",2,"op","chess_char_6_diy2_b",1,"uniequip_002_narant",2331,1,171,1,183931,4662,0,52,2],
|
||||
["p1",3,"op","chess_char_6_diy1_b",2,"uniequip_002_narant",0,0,138,4,181139,4662,0,42,1],
|
||||
["p1",4,"op","chess_char_6_diy2_b",0,"uniequip_003_narant",0,0,148,1,247083,5262,0,47,2],
|
||||
["p1",5,"op","chess_char_6_diy1_b",1,"uniequip_003_narant",484.58,1,159,9,431571,4777,0,75,2],
|
||||
["p1",6,"op","chess_char_6_diy2_b",2,"uniequip_003_narant",2105.15,1,168,4,115965,5788,0,57,2],
|
||||
["p1",7,"op","chess_char_5_diy1_a",0,null,0,0,78,0,3199,2594,0,6,0],
|
||||
["p1",8,"op","chess_char_5_diy2_a",1,null,0,0,7,0,11162,1297,0,23,1],
|
||||
["p1",9,"op","chess_char_5_diy1_a",2,null,0,0,84,0,5660,2594,0,10,0],
|
||||
["p1",10,"op","chess_char_5_diy2_b",0,"none",0,0,83,0,4405,3080,0,8,0],
|
||||
["p1",11,"op","chess_char_5_diy1_b",1,"none",0,0,4,1,23711,1540,0,39,1],
|
||||
["p1",12,"op","chess_char_5_diy2_b",2,"none",0,0,93,0,8419,3080,0,13,0]
|
||||
],
|
||||
"enemies": {"enemy_1010_demon_2":[36,1,35,20195,818412],"enemy_1071_dftman":[51,12,39,4233,376807],"enemy_1072_dlancer":[60,10,50,15864,496164]},
|
||||
"hooks": [1,171,6394,534,534,1265,1244,0,44,168,13,11,0,6032,182,35,147,124,1,44,0,0,21],
|
||||
"events": {"atk":534,"deploy":24,"die":44,"dmg":1244,"engage":12,"fx":455,"leak":124,"skill":24,"spawn":159,"status":268},
|
||||
"fx": {"aoe":28,"bounce":344,"dodge":58,"logosLexicon":25},
|
||||
"snaps": "46cae241 4126bfe2 3597168d ef44620e 25aa24d2 bef8ed11 e114314a 75ea4626 14a7267e d136ce0e cd0f1cb6 a5f2f534 04f217e4 84e96cae e87a36e7 163b985d 0de49904 6dbacbcc 41cdeac6 9bb308c2 40ba42e6 1823cbb2"
|
||||
"enemies": {"enemy_1010_demon_2":[36,3,33,28588,679603],"enemy_1071_dftman":[51,12,39,4181,301561],"enemy_1072_dlancer":[60,9,51,11229,460211]},
|
||||
"hooks": [1,171,6284,545,545,1173,1145,0,45,168,13,12,0,6532,195,41,147,123,1,46,0,0,28],
|
||||
"events": {"atk":545,"deploy":24,"die":45,"dmg":1145,"engage":12,"fx":358,"leak":123,"skill":25,"spawn":159,"status":262},
|
||||
"fx": {"aoe":29,"bounce":228,"dodge":62,"logosLexicon":39},
|
||||
"snaps": "a3f1b53f 65ad96a3 1e27c835 c471b183 a9d117e1 1230958c c5f01b31 e2f16dc4 13b7ff34 fff6f70c ff28c518 960ad469 07783e9f cfb1dd16 eb64d4e5 b8b84845 95ff5870 65dcc089 4092ee32 0fa97a73 4c82d2a7"
|
||||
},
|
||||
"diy-029": {
|
||||
"about": "5_diy1_b=logos/S1/002_logos 5_diy2_b=logos/S2/002_logos 5_diy1_b=logos/S3/002_logos 5_diy2_b=logos/S1/003_logos 5_diy1_b=logos/S2/003_logos 5_diy2_b=logos/S3/003_logos 6_diy1_a=logos/S1 6_diy2_a=logos/S2 6_diy1_a=logos/S3 6_diy2_b=logos/S1 6_diy1_b=logos/S2 6_diy2_b=logos/S3",
|
||||
@@ -5305,35 +5305,35 @@
|
||||
"time": 230,
|
||||
"ticks": 6900,
|
||||
"reason": "timeout",
|
||||
"killed": 3,
|
||||
"killed": 2,
|
||||
"total": 147,
|
||||
"unspawned": 0,
|
||||
"bossHpLeft": null,
|
||||
"rngDraws": 0,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {"p1":{"killed":3,"total":147,"perfect":false,"leaks":144,"leaksUncounted":0,"coins":0,"dmg":348342,"bossDmg":0,"heal":121624,"deaths":2,"layerGains":{}}},
|
||||
"players": {"p1":{"killed":2,"total":147,"perfect":false,"leaks":145,"leaksUncounted":0,"coins":0,"dmg":361912,"bossDmg":0,"heal":143362,"deaths":1,"layerGains":{}}},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_6_diy1_b",0,"uniequip_002_slent2",2298,1,6,1,21379,0,26921,120,4],
|
||||
["p1",2,"op","chess_char_6_diy2_b",1,"uniequip_002_slent2",2298,1,11,0,31263,0,8537,126,5],
|
||||
["p1",3,"op","chess_char_6_diy1_b",2,"uniequip_002_slent2",2298,1,14,1,18776,0,10738,96,2],
|
||||
["p1",4,"op","chess_char_6_diy2_b",0,"uniequip_003_slent2",1965,1,4,0,31475,0,6332,77,4],
|
||||
["p1",5,"op","chess_char_6_diy1_b",1,"uniequip_003_slent2",1965,1,5,0,48142,0,4350,114,5],
|
||||
["p1",6,"op","chess_char_6_diy2_b",2,"uniequip_003_slent2",2358,1,7,0,29166,22769,17305,107,2],
|
||||
["p1",7,"op","chess_char_5_diy1_a",0,null,1556.5,1,12,0,17432,0,7466,103,5],
|
||||
["p1",8,"op","chess_char_5_diy2_a",1,null,1556.5,1,15,0,23629,0,9192,52,2],
|
||||
["p1",9,"op","chess_char_5_diy1_a",2,null,1546,1,8,1,34961,32714,8309,102,3],
|
||||
["p1",10,"op","chess_char_5_diy2_b",0,"none",1900.8,1,10,0,20476,27840,7147,103,5],
|
||||
["p1",11,"op","chess_char_5_diy1_b",1,"none",1900.8,1,85,0,43974,20825,6683,53,2],
|
||||
["p1",12,"op","chess_char_5_diy2_b",2,"none",1900.8,1,157,0,27668,21289,8644,69,2],
|
||||
["p1",1,"op","chess_char_6_diy1_b",0,"uniequip_002_slent2",2298,1,6,0,21216,0,29039,124,4],
|
||||
["p1",2,"op","chess_char_6_diy2_b",1,"uniequip_002_slent2",2298,1,11,1,30725,0,10525,133,5],
|
||||
["p1",3,"op","chess_char_6_diy1_b",2,"uniequip_002_slent2",2298,1,14,0,18054,0,12278,94,2],
|
||||
["p1",4,"op","chess_char_6_diy2_b",0,"uniequip_003_slent2",1965,1,4,0,31024,0,8511,82,4],
|
||||
["p1",5,"op","chess_char_6_diy1_b",1,"uniequip_003_slent2",1965,1,5,0,45080,0,5550,106,5],
|
||||
["p1",6,"op","chess_char_6_diy2_b",2,"uniequip_003_slent2",2358,1,7,1,31619,19740,20167,112,2],
|
||||
["p1",7,"op","chess_char_5_diy1_a",0,null,1556.5,1,12,0,17910,0,9908,113,5],
|
||||
["p1",8,"op","chess_char_5_diy2_a",1,null,1556.5,1,15,0,22693,0,7723,50,2],
|
||||
["p1",9,"op","chess_char_5_diy1_a",2,null,842.5,1,8,0,29890,48209,8088,107,3],
|
||||
["p1",10,"op","chess_char_5_diy2_b",0,"none",1900.8,1,10,0,20476,30138,9922,112,5],
|
||||
["p1",11,"op","chess_char_5_diy1_b",1,"none",1900.8,1,85,0,50279,20651,7939,57,2],
|
||||
["p1",12,"op","chess_char_5_diy2_b",2,"none",1900.8,1,9,0,42947,27240,13712,119,3],
|
||||
["-","~1","device","trap_1105_accrate",null,null,100,1,1,0,0,0,0,0,null],
|
||||
["-","~2","device","trap_1105_accrate",null,null,100,1,2,0,0,0,0,0,null],
|
||||
["-","~3","device","trap_1105_accrate",null,null,100,1,3,0,0,0,0,0,null]
|
||||
],
|
||||
"enemies": {"enemy_1010_demon_2":[36,0,36,34867,60280],"enemy_1071_dftman":[51,1,50,11383,65774],"enemy_1072_dlancer":[60,2,56,79187,222288]},
|
||||
"hooks": [1,164,6900,1364,1364,1576,1576,650,5,147,41,38,0,41208,54,57,147,142,1,5,0,0,0],
|
||||
"events": {"atk":1546,"deploy":14,"die":5,"dmg":1570,"engage":12,"fx":607,"heal":388,"leak":142,"skill":79,"spawn":162,"status":589},
|
||||
"fx": {"aoe":72,"heal":231,"levitate":54,"shield":250},
|
||||
"snaps": "0fc819e5 0de8f25c cbd99739 53bf2362 bf211e55 3b1d12b8 0ac8e0aa 9dba465e 5c93fe8c 41f070f9 c15b74b1 e8c12aaa 5e0dcaaa 4ae2edb1 c8d02dee 9098c07b 573d1807 e87ef02e 54edadf7 7f5feeb6 a1637ee7 6473e5cd 28977ec1"
|
||||
"enemies": {"enemy_1010_demon_2":[36,0,35,51346,79660],"enemy_1071_dftman":[51,0,51,2463,49416],"enemy_1072_dlancer":[60,2,55,92168,232837]},
|
||||
"hooks": [1,163,6900,1481,1481,1677,1677,699,3,144,42,38,0,42822,48,52,147,141,1,3,0,0,0],
|
||||
"events": {"atk":1676,"deploy":13,"die":3,"dmg":1669,"engage":12,"fx":667,"heal":473,"leak":141,"skill":80,"spawn":162,"status":641},
|
||||
"fx": {"aoe":77,"heal":263,"levitate":48,"shield":279},
|
||||
"snaps": "0fc819e5 0de8f25c cbd99739 77c95ad9 8647c63d 61c97ad4 b295ab13 ae5b7267 75d5473a bf103537 52a28a1a e92bdbc7 726765f0 32462a64 73f3b008 4a5d58d5 f54e088a 3bc5d685 8664c2c2 3d0b0f6a 78392737 747f298e f70dc197"
|
||||
},
|
||||
"diy-125": {
|
||||
"about": "5_diy1_b=haruka/S1/002_haruka 5_diy2_b=haruka/S2/002_haruka 5_diy1_b=haruka/S3/002_haruka 6_diy1_a=haruka/S1 6_diy2_a=haruka/S2 6_diy1_a=haruka/S3 6_diy2_b=haruka/S1 6_diy1_b=haruka/S2 6_diy2_b=haruka/S3 6_diy1_b=haruka/S1/002_haruka 6_diy2_b=haruka/S2/002_haruka 6_diy1_b=haruka/S3/002_haruka",
|
||||
|
||||
+380
-346
@@ -138,45 +138,78 @@
|
||||
"time": 200,
|
||||
"ticks": 6000,
|
||||
"reason": "forced",
|
||||
"killed": 7,
|
||||
"killed": 8,
|
||||
"total": 8,
|
||||
"unspawned": 0,
|
||||
"bossHpLeft": 5323494,
|
||||
"rngDraws": 861,
|
||||
"bossHpLeft": 5364478,
|
||||
"rngDraws": 913,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {
|
||||
"p1": {"killed":7,"total":8,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":591887,"bossDmg":312274,"heal":19641,"deaths":0,"layerGains":{}},
|
||||
"p2": {"killed":0,"total":0,"perfect":false,"leaks":1,"leaksUncounted":0,"coins":0,"dmg":878330,"bossDmg":361136,"heal":6843,"deaths":1,"layerGains":{}}
|
||||
"p1": {"killed":8,"total":8,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":616081,"bossDmg":345229,"heal":26489,"deaths":2,"layerGains":{}},
|
||||
"p2": {"killed":0,"total":0,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":880840,"bossDmg":287130,"heal":5585,"deaths":1,"layerGains":{}}
|
||||
},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_5_19_b",2,"uniequip_002_mlynar",3907,1,9,0,176503,1132,0,72,3],
|
||||
["p1",2,"op","chess_char_4_01_b",2,"uniequip_002_rmixer",5482.35,1,11,0,723,12906,183,34,1],
|
||||
["p1",3,"op","chess_char_5_14_b",1,"none",1994,1,7,0,26692,1028,261,54,14],
|
||||
["p1",4,"op","chess_char_5_17_b",1,"uniequip_002_f12yin",2738,1,13,0,13640,0,0,80,1],
|
||||
["p1",5,"op","chess_char_5_15_b",1,"uniequip_002_thorn2",1170,1,1,0,59962,0,1515,33,6],
|
||||
["p1",6,"op","chess_char_5_20_b",2,"uniequip_002_aglina",2418.5,1,3,0,72626,0,0,43,4],
|
||||
["p1",7,"op","chess_char_5_21_b",1,"uniequip_002_sntlla",2769.3,1,17,0,28364,0,0,57,3],
|
||||
["p1",8,"op","chess_char_5_22_b",1,"uniequip_002_nymph",1611,1,19,4,174454,2047,1463,57,21],
|
||||
["p1",9,"op","chess_char_5_23_b",1,"uniequip_002_reckpr",1610,1,5,0,0,0,16175,20,3],
|
||||
["p1",10,"op","chess_char_4_02_b",2,"uniequip_002_mostma",1695,1,15,0,38923,1393,44,40,2],
|
||||
["p2",11,"op","chess_char_4_11_b",1,"uniequip_002_cathy",599.39,1,12,0,0,3929,1201,0,2],
|
||||
["p2",12,"op","chess_char_4_04_b",1,"uniequip_002_ines",3545.85,1,48,1,241366,511,511,284,8],
|
||||
["p2",13,"op","chess_char_4_07_b",1,"uniequip_002_bpipe",1898.31,1,8,0,2347,1249,764,15,6],
|
||||
["p2",14,"op","chess_char_4_16_b",2,"uniequip_002_texas2",2671.35,1,47,1,101686,2806,1366,162,10],
|
||||
["p2",15,"op","chess_char_4_09_b",1,"uniequip_002_mizuki",1931.91,1,10,0,56922,1270,424,53,3],
|
||||
["p2",16,"op","chess_char_4_06_b",1,"uniequip_002_kroos2",1561,1,2,0,275392,0,0,175,2],
|
||||
["p1",1,"op","chess_char_5_19_b",2,"uniequip_002_mlynar",3907,1,9,0,197572,2597,100,74,3],
|
||||
["p1",2,"op","chess_char_4_01_b",2,"uniequip_002_rmixer",3537,1,11,0,17911,21305,253,56,1],
|
||||
["p1",3,"op","chess_char_5_14_b",1,"none",1994,1,7,0,23508,1118,106,12,14],
|
||||
["p1",4,"op","chess_char_5_17_b",1,"uniequip_002_f12yin",2738,1,13,0,1795,0,0,14,1],
|
||||
["p1",5,"op","chess_char_5_15_b",1,"uniequip_002_thorn2",1170,1,1,0,130284,0,7756,70,11],
|
||||
["p1",6,"op","chess_char_5_20_b",2,"uniequip_002_aglina",2418.5,1,3,0,59757,0,0,44,4],
|
||||
["p1",7,"op","chess_char_5_21_b",1,"uniequip_002_sntlla",2769.3,1,45,2,26256,3155,385,54,2],
|
||||
["p1",8,"op","chess_char_5_22_b",1,"uniequip_002_nymph",1611,1,43,0,112386,1831,220,45,16],
|
||||
["p1",9,"op","chess_char_5_23_b",1,"uniequip_002_reckpr",1610,1,5,0,0,0,17669,25,3],
|
||||
["p1",10,"op","chess_char_4_02_b",2,"uniequip_002_mostma",1695,1,15,1,46613,1393,0,31,2],
|
||||
["p2",11,"op","chess_char_4_11_b",1,"uniequip_002_cathy",965.67,1,12,0,0,3839,1557,0,2],
|
||||
["p2",12,"op","chess_char_4_04_b",1,"uniequip_002_ines",3545.85,1,46,2,233157,0,0,265,6],
|
||||
["p2",13,"op","chess_char_4_07_b",1,"uniequip_002_bpipe",2236.31,1,8,0,2429,1159,1012,15,6],
|
||||
["p2",14,"op","chess_char_4_16_b",2,"uniequip_002_texas2",2671.35,1,44,0,59323,1488,148,88,7],
|
||||
["p2",15,"op","chess_char_4_09_b",1,"uniequip_002_mizuki",2777.6,1,10,0,73699,0,0,69,4],
|
||||
["p2",16,"op","chess_char_4_06_b",1,"uniequip_002_kroos2",1561,1,2,1,332967,0,0,251,3],
|
||||
["p2",17,"op","chess_char_4_10_b",1,"uniequip_002_aroma",1664,1,4,0,0,0,0,0,0],
|
||||
["p2",18,"op","chess_char_4_12_b",2,"uniequip_002_glady",1636.54,1,18,1,44668,3170,2575,41,4],
|
||||
["p2",19,"op","chess_char_4_13_b",1,"uniequip_002_gnosis",1989,1,41,0,62779,1991,2,96,26],
|
||||
["p2",20,"op","chess_char_4_14_b",1,"uniequip_002_lionhd",1626,1,6,0,93170,0,0,61,17],
|
||||
["p2",18,"op","chess_char_4_12_b",2,"uniequip_002_glady",1857.24,1,18,1,46534,3241,2866,40,3],
|
||||
["p2",19,"op","chess_char_4_13_b",1,"uniequip_002_gnosis",1989,1,41,1,50318,1991,2,69,19],
|
||||
["p2",20,"op","chess_char_4_14_b",1,"uniequip_002_lionhd",1626,1,6,0,82414,0,0,54,13],
|
||||
["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_1005_yokai_2":[6,6,0,3187,62190],"enemy_1430_lrrook":[2,1,1,0,734721],"enemy_9017_achunt":[2,0,0,30243,676506]},
|
||||
"hooks": [1,46,6000,1359,1379,2883,2933,5284,9,22,136,129,20,37832,1034,0,10,1,1,9,0,12,0],
|
||||
"events": {"atk":1384,"deploy":36,"die":21,"dmg":2925,"engage":17,"fx":608,"heal":50,"leak":1,"skill":265,"spawn":32,"status":505},
|
||||
"fx": {"aoe":38,"appear":2,"blink":13,"burst":12,"catShield":1,"charge":6,"counter":20,"crit":105,"dilemma":3,"disappear":2,"explosion":17,"frostNova":26,"garrisonGrant":1,"iceSpike":53,"overclock":2,"pull":3,"quadShot":2,"ripple":20,"sentry":5,"sermon":1,"shadowWeave":10,"shield":5,"soul":6,"sp":8,"stealth":8,"swordRain":91,"swordStorm":10,"tornado":4,"tornadoPulse":16,"weightless":4,"zone":114},
|
||||
"snaps": "8c0abe54 9b607288 336a3889 ab855b37 55a7f144 2239f0b8 855b08a6 d6883aa1 06da7541 da586a98 f0803d88 8d33a16a c1c54b58 68e1874e a0524730 737daaf0 ebd64be9 ec096e18 d99e1d14 bf343ba5"
|
||||
"enemies": {"enemy_1005_yokai_2":[6,6,0,5219,62190],"enemy_1430_lrrook":[2,2,0,0,802449],"enemy_9017_achunt":[2,0,0,37896,635522]},
|
||||
"hooks": [1,44,6000,1296,1320,2757,2793,4386,11,20,120,118,30,38324,958,0,10,0,1,11,0,10,1],
|
||||
"events": {"atk":1325,"deploy":34,"die":20,"dmg":2785,"engage":17,"fx":668,"heal":107,"skill":238,"spawn":32,"status":453},
|
||||
"fx": {
|
||||
"aoe": 37,
|
||||
"appear": 2,
|
||||
"blink": 9,
|
||||
"burst": 10,
|
||||
"catShield": 1,
|
||||
"charge": 6,
|
||||
"counter": 30,
|
||||
"crit": 126,
|
||||
"dilemma": 4,
|
||||
"disappear": 2,
|
||||
"dodge": 1,
|
||||
"explosion": 13,
|
||||
"frostNova": 19,
|
||||
"garrisonGrant": 1,
|
||||
"iceSpike": 48,
|
||||
"overclock": 2,
|
||||
"pull": 3,
|
||||
"quadShot": 3,
|
||||
"ripple": 20,
|
||||
"sentry": 3,
|
||||
"sermon": 1,
|
||||
"shadowWeave": 7,
|
||||
"shield": 7,
|
||||
"soul": 3,
|
||||
"sp": 10,
|
||||
"stealth": 6,
|
||||
"swordRain": 56,
|
||||
"swordStorm": 7,
|
||||
"tornado": 3,
|
||||
"tornadoPulse": 15,
|
||||
"weightless": 4,
|
||||
"zone": 209
|
||||
},
|
||||
"snaps": "8c0abe54 9b607288 941cd501 25535c11 fb3139ca 9fef10e6 862493a5 c02461d1 7a7b723d e92ed2e1 87505792 02ea30b3 7ca8af6e e52d3d9d 68f1a4d7 7258cbc2 76a4c411 046e818b 2e54adea aa8b9cc0"
|
||||
},
|
||||
"boss-boss_2-solo": {
|
||||
"about": "假想敌:铳 solo pool 3000000: 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",
|
||||
@@ -230,102 +263,98 @@
|
||||
"killed": 21,
|
||||
"total": 21,
|
||||
"unspawned": 0,
|
||||
"bossHpLeft": 32389,
|
||||
"rngDraws": 1396,
|
||||
"bossHpLeft": 145080,
|
||||
"rngDraws": 1385,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {
|
||||
"p1": {"killed":21,"total":21,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":1695850,"bossDmg":1631787,"heal":2418,"deaths":0,"layerGains":{}},
|
||||
"p2": {"killed":0,"total":0,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":2455567,"bossDmg":2335824,"heal":25654,"deaths":0,"layerGains":{}}
|
||||
"p1": {"killed":21,"total":21,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":1679564,"bossDmg":1583484,"heal":2172,"deaths":0,"layerGains":{}},
|
||||
"p2": {"killed":0,"total":0,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":2359162,"bossDmg":2271437,"heal":16328,"deaths":0,"layerGains":{}}
|
||||
},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_6_03_b",2,"uniequip_002_yu",3430,1,7,0,0,0,0,0,0],
|
||||
["p1",1,"op","chess_char_6_03_b",2,"uniequip_002_yu",3430,1,7,0,0,0,605,0,1],
|
||||
["p1",2,"op","chess_char_6_06_b",2,"uniequip_002_pepe",2939,1,11,0,0,0,0,0,0],
|
||||
["p1",3,"op","chess_char_6_07_b",2,"uniequip_002_siege2",3101,1,9,0,0,0,0,0,0],
|
||||
["p1",4,"op","chess_char_6_01_b",2,"uniequip_002_lemuen",2131.5,1,13,2,904165,0,0,62,8],
|
||||
["p1",5,"op","chess_char_6_02_b",2,"uniequip_002_sbell2",1933,1,17,2,323380,39,5,62,3],
|
||||
["p1",6,"op","chess_char_6_04_b",2,"uniequip_002_skadi2",1214.37,1,19,1,36269,8963,1922,0,5],
|
||||
["p1",7,"op","chess_char_6_05_b",2,"uniequip_002_pasngr",2307.2,1,21,1,303279,1552,491,96,8],
|
||||
["p1",8,"op","chess_char_6_08_b",2,"uniequip_002_reed2",1668,1,5,0,0,0,0,0,0],
|
||||
["p1",9,"op","chess_char_6_09_b",0,"uniequip_002_cello",1322,1,15,1,10,0,0,3,3],
|
||||
["p1",10,"op","chess_char_6_11_b",2,"uniequip_002_mlyss",1893,1,23,0,89889,0,0,207,5],
|
||||
["p1",4,"op","chess_char_6_01_b",2,"uniequip_002_lemuen",2131.5,1,13,1,877126,0,0,62,8],
|
||||
["p1",5,"op","chess_char_6_02_b",2,"uniequip_002_sbell2",1933,1,17,0,349841,28,2,63,3],
|
||||
["p1",6,"op","chess_char_6_04_b",2,"uniequip_002_skadi2",1214.37,1,19,1,35820,8433,1241,0,5],
|
||||
["p1",7,"op","chess_char_6_05_b",2,"uniequip_002_pasngr",2307.2,1,21,2,293209,1008,323,97,8],
|
||||
["p1",8,"op","chess_char_6_08_b",2,"uniequip_002_reed2",1668,1,5,1,3064,0,1,11,1],
|
||||
["p1",9,"op","chess_char_6_09_b",0,"uniequip_002_cello",1322,1,15,1,21050,0,0,8,8],
|
||||
["p1",10,"op","chess_char_6_11_b",2,"uniequip_002_mlyss",1893,1,23,0,89834,0,0,206,5],
|
||||
["p1",11,"token","token_10017_skadi2_dedant",null,null,130.4,0,26,0,0,0,0,0,null],
|
||||
["p2",12,"op","chess_char_6_15_b",2,"uniequip_002_qiubai",3801.6,1,31,1,449725,8103,1186,204,3],
|
||||
["p2",13,"op","chess_char_6_19_b",2,"uniequip_002_blkkgt",2767,1,12,1,16446,0,0,3,1],
|
||||
["p2",14,"op","chess_char_5_01_b",1,"uniequip_002_excu2",1653.08,1,10,1,6,1222,360,6,1],
|
||||
["p2",15,"op","chess_char_6_17_b",2,"uniequip_002_nearl2",6215.89,1,32,0,268872,836,0,81,4],
|
||||
["p2",16,"op","chess_char_6_12_b",1,"uniequip_002_rosmon",3117.74,1,16,3,190441,856,166,73,4],
|
||||
["p2",17,"op","chess_char_6_13_b",1,"uniequip_002_angel2",2392.2,1,20,2,1232637,5257,991,368,6],
|
||||
["p2",18,"op","chess_char_6_14_b",2,"uniequip_002_lumen",2050.92,1,22,0,0,2064,3414,47,1],
|
||||
["p2",19,"op","chess_char_6_16_b",2,"uniequip_002_halo2",1554.12,1,25,1,79495,579,0,148,4],
|
||||
["p2",20,"op","chess_char_6_18_b",2,"uniequip_002_whitw2",1541,1,6,5,181467,0,0,11,3],
|
||||
["p2",21,"op","chess_char_6_20_b",2,"uniequip_002_agoat2",1631.88,1,18,0,0,0,19537,50,2],
|
||||
["p2",12,"op","chess_char_6_15_b",2,"uniequip_002_qiubai",3985.92,1,31,6,345376,3222,0,183,3],
|
||||
["p2",13,"op","chess_char_6_19_b",2,"uniequip_002_blkkgt",2767,1,12,1,27218,0,0,6,1],
|
||||
["p2",14,"op","chess_char_5_01_b",1,"uniequip_002_excu2",2314,1,10,0,0,0,0,0,0],
|
||||
["p2",15,"op","chess_char_6_17_b",2,"uniequip_002_nearl2",6215.89,1,46,0,293226,0,0,85,4],
|
||||
["p2",16,"op","chess_char_6_12_b",1,"uniequip_002_rosmon",3117.74,1,16,2,189809,0,0,74,4],
|
||||
["p2",17,"op","chess_char_6_13_b",1,"uniequip_002_angel2",2392.2,1,20,3,1205701,5257,423,365,6],
|
||||
["p2",18,"op","chess_char_6_14_b",2,"uniequip_002_lumen",2050.92,1,22,0,0,0,2846,42,1],
|
||||
["p2",19,"op","chess_char_6_16_b",2,"uniequip_002_halo2",1554.12,1,25,0,87945,932,0,163,4],
|
||||
["p2",20,"op","chess_char_6_18_b",2,"uniequip_002_whitw2",1541,1,6,3,182528,0,0,13,3],
|
||||
["p2",21,"op","chess_char_6_20_b",2,"uniequip_002_agoat2",1631.88,1,18,0,0,0,13059,42,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],
|
||||
["-","~3","device","trap_1105_accrate",null,null,100,1,3,0,0,0,0,0,null],
|
||||
["-","~4","device","trap_1105_accrate",null,null,100,1,4,0,0,0,0,0,null],
|
||||
["p1","~1","token","token_10030_mlyss_wtrman",null,null,0,0,24,0,8296,1880,0,17,1],
|
||||
["p2","~1","token","token_10019_nearl2_sword",null,null,7824,0,41,0,9120,0,0,0,null],
|
||||
["p1","~2","token","token_10030_mlyss_wtrman",null,null,860.02,0,42,0,1348,1020,0,2,null],
|
||||
["p1","~1","token","token_10017_skadi2_dedant",null,null,100,0,47,0,0,0,0,0,null],
|
||||
["p1","~3","token","token_10030_mlyss_wtrman",null,null,1557.36,1,50,0,29214,0,0,62,1],
|
||||
["p2","~2","token","token_10019_nearl2_sword",null,null,6480,0,51,0,9120,0,0,0,null],
|
||||
["p1","~4","token","token_10030_mlyss_wtrman",null,null,1880.37,0,53,0,0,0,0,0,null],
|
||||
["p1","~2","token","token_10017_skadi2_dedant",null,null,130.4,0,55,0,0,0,0,0,null],
|
||||
["p1","~5","token","token_10030_mlyss_wtrman",null,null,1880.37,0,57,0,0,0,0,0,null],
|
||||
["p2","~3","token","token_10019_nearl2_sword",null,null,6480,0,58,0,9120,0,0,0,null],
|
||||
["p1","~3","token","token_10017_skadi2_dedant",null,null,100,0,61,0,0,0,0,0,null],
|
||||
["p1","~6","token","token_10030_mlyss_wtrman",null,null,1557.36,0,62,0,0,0,0,0,null],
|
||||
["p2","~4","token","token_10019_nearl2_sword",null,null,6480,1,64,0,9120,0,0,0,null]
|
||||
["p1","~1","token","token_10030_mlyss_wtrman",null,null,0,0,24,0,8947,1880,0,18,1],
|
||||
["p1","~2","token","token_10030_mlyss_wtrman",null,null,860.02,0,41,0,674,1020,0,1,null],
|
||||
["p1","~1","token","token_10017_skadi2_dedant",null,null,100,0,48,0,0,0,0,0,null],
|
||||
["p2","~1","token","token_10019_nearl2_sword",null,null,6480,0,50,0,9120,0,0,0,null],
|
||||
["p1","~2","token","token_10017_skadi2_dedant",null,null,130.4,0,53,0,0,0,0,0,null],
|
||||
["p2","~2","token","token_10019_nearl2_sword",null,null,6480,0,55,0,9120,0,0,0,null],
|
||||
["p1","~3","token","token_10017_skadi2_dedant",null,null,100,0,57,0,0,0,0,0,null],
|
||||
["p2","~3","token","token_10019_nearl2_sword",null,null,6480,1,60,0,9120,0,0,0,null]
|
||||
],
|
||||
"enemies": {
|
||||
"enemy_1197_sfshu_2": [2,2,0,0,28809],
|
||||
"enemy_1198_msfshu_2": [6,6,0,0,24],
|
||||
"enemy_1209_sfden_2": [2,2,0,11003,154793],
|
||||
"enemy_1209_sfden_2": [2,2,0,2901,154793],
|
||||
"enemy_1210_msfden_2": [2,2,0,0,90],
|
||||
"enemy_9021_acduml": [1,0,0,0,3967611],
|
||||
"enemy_9023_acdums": [9,9,0,8178,90]
|
||||
"enemy_9021_acduml": [1,0,0,0,3854920],
|
||||
"enemy_9023_acdums": [9,9,0,5690,90]
|
||||
},
|
||||
"hooks": [1,62,6000,1512,1512,3171,3572,2628,22,35,63,56,376,44379,1588,4,22,0,1,22,0,1,0],
|
||||
"events": {"atk":1661,"deploy":36,"die":35,"dmg":3271,"engage":16,"fx":1035,"heal":306,"skill":119,"spawn":60,"status":513},
|
||||
"hooks": [1,58,6000,1444,1444,3043,3408,2091,22,32,68,62,368,46997,1658,3,22,0,1,22,0,2,0],
|
||||
"events": {"atk":1595,"deploy":32,"die":32,"dmg":3120,"engage":15,"fx":1016,"heal":279,"skill":130,"spawn":55,"status":503},
|
||||
"fx": {
|
||||
"airstrike": 135,
|
||||
"airstrike": 121,
|
||||
"appear": 1,
|
||||
"beam": 9,
|
||||
"blink": 2,
|
||||
"bombard": 66,
|
||||
"bombardShell": 66,
|
||||
"blink": 3,
|
||||
"bombard": 65,
|
||||
"bombardShell": 65,
|
||||
"buff": 3,
|
||||
"burst": 1,
|
||||
"copy": 2,
|
||||
"burst": 2,
|
||||
"copy": 1,
|
||||
"disappear": 1,
|
||||
"displace": 2,
|
||||
"displace": 3,
|
||||
"dp": 5,
|
||||
"drone": 339,
|
||||
"droneLock": 17,
|
||||
"drone": 338,
|
||||
"droneLock": 16,
|
||||
"drones": 3,
|
||||
"explode": 138,
|
||||
"extraAttack": 1,
|
||||
"explode": 132,
|
||||
"finale": 1,
|
||||
"firewall": 1,
|
||||
"garrisonGrant": 1,
|
||||
"lightning": 74,
|
||||
"link": 5,
|
||||
"lock": 66,
|
||||
"lightning": 73,
|
||||
"link": 6,
|
||||
"lock": 65,
|
||||
"lure": 3,
|
||||
"phase": 18,
|
||||
"radiantSword": 4,
|
||||
"radiantSword": 3,
|
||||
"scorchBurst": 2,
|
||||
"slash": 11,
|
||||
"snow": 11,
|
||||
"split": 4,
|
||||
"snow": 16,
|
||||
"split": 1,
|
||||
"steal": 6,
|
||||
"storm": 8,
|
||||
"summon": 15,
|
||||
"sunBurst": 1,
|
||||
"summon": 14,
|
||||
"sunBurst": 3,
|
||||
"talent": 4,
|
||||
"telegraph": 4,
|
||||
"tide": 5,
|
||||
"wanted": 3
|
||||
},
|
||||
"snaps": "87a11c35 cc0e1f70 2de88ef7 a5a4efc1 36878065 d2f20d65 a5481200 93371ab3 fa830c40 8d59e885 222cca53 040b3f01 dc7f3982 cca5f067 8a116542 f1f56dac c68f3562 6833a03c 12743320 0f665121"
|
||||
"snaps": "4c79f145 ebcda26d 068f0e59 260d03ab 4d134b3f 2defd0f7 5961828b 506fed72 8d5f31a0 89f65c2c 33bc87a4 4451906c 9a5ad227 eaf78a06 8f5bd27e 328395fb 4390b356 8ef50254 ad617400 7fb9bf40"
|
||||
},
|
||||
"boss-boss_3-solo": {
|
||||
"about": "假想敌:管 solo pool 2000000: chess_char_5_08_b chess_char_5_11_b chess_char_5_05_b chess_char_5_06_b chess_char_5_13_b chess_char_5_07_b chess_char_5_02_b chess_char_5_03_b chess_char_5_10_b chess_char_5_12_b",
|
||||
@@ -390,81 +419,81 @@
|
||||
"time": 200,
|
||||
"ticks": 6000,
|
||||
"reason": "forced",
|
||||
"killed": 9,
|
||||
"killed": 12,
|
||||
"total": 14,
|
||||
"unspawned": 0,
|
||||
"bossHpLeft": 7601883,
|
||||
"rngDraws": 496,
|
||||
"bossHpLeft": 7548877,
|
||||
"rngDraws": 541,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {
|
||||
"p1": {"killed":9,"total":14,"perfect":false,"leaks":3,"leaksUncounted":0,"coins":0,"dmg":832066,"bossDmg":272991,"heal":24644,"deaths":21,"layerGains":{}},
|
||||
"p2": {"killed":0,"total":0,"perfect":false,"leaks":2,"leaksUncounted":0,"coins":0,"dmg":815098,"bossDmg":525125,"heal":3151,"deaths":24,"layerGains":{}}
|
||||
"p1": {"killed":12,"total":14,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":893986,"bossDmg":308902,"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,51,3,138264,7838,24,22,1],
|
||||
["p1",2,"op","chess_char_4_01_b",2,"uniequip_002_rmixer",0,0,5,0,16815,6179,893,10,1],
|
||||
["p1",3,"op","chess_char_5_14_b",1,"none",0,0,62,0,49407,10951,912,3,8],
|
||||
["p1",4,"op","chess_char_5_17_b",1,"uniequip_002_f12yin",0,0,59,0,4545,12126,187,2,1],
|
||||
["p1",5,"op","chess_char_5_15_b",1,"uniequip_002_thorn2",751.16,1,66,2,302889,4343,4325,83,13],
|
||||
["p1",6,"op","chess_char_5_20_b",2,"uniequip_002_aglina",0,0,60,1,81029,10790,504,39,4],
|
||||
["p1",7,"op","chess_char_5_21_b",1,"uniequip_002_sntlla",0,0,19,0,91590,2005,24,110,3],
|
||||
["p1",8,"op","chess_char_5_22_b",1,"uniequip_002_nymph",0,0,56,2,61149,3914,692,30,11],
|
||||
["p1",9,"op","chess_char_5_23_b",1,"uniequip_002_reckpr",0,0,57,0,0,4410,17059,32,3],
|
||||
["p1",10,"op","chess_char_4_02_b",2,"uniequip_002_mostma",0,0,15,0,86379,2071,24,36,2],
|
||||
["p2",11,"op","chess_char_4_11_b",1,"uniequip_002_cathy",0,0,50,0,0,6877,135,0,1],
|
||||
["p2",12,"op","chess_char_4_04_b",1,"uniequip_002_ines",1827.12,1,68,0,125101,9355,115,125,6],
|
||||
["p2",13,"op","chess_char_4_07_b",1,"uniequip_002_bpipe",0,0,65,0,26395,7425,67,37,9],
|
||||
["p2",14,"op","chess_char_4_16_b",2,"uniequip_002_texas2",0,0,63,0,103636,9247,100,151,6],
|
||||
["p2",15,"op","chess_char_4_09_b",1,"uniequip_002_mizuki",0,0,55,0,185661,6408,233,40,4],
|
||||
["p2",16,"op","chess_char_4_06_b",1,"uniequip_002_kroos2",0,0,58,0,114013,3511,389,114,2],
|
||||
["p2",17,"op","chess_char_4_10_b",1,"uniequip_002_aroma",0,0,14,0,0,3417,24,0,0],
|
||||
["p2",18,"op","chess_char_4_12_b",2,"uniequip_002_glady",0,0,64,0,61768,6768,1277,69,4],
|
||||
["p2",19,"op","chess_char_4_13_b",1,"uniequip_002_gnosis",0,0,61,0,53260,4339,361,56,16],
|
||||
["p2",20,"op","chess_char_4_14_b",1,"uniequip_002_lionhd",0,0,67,1,145265,3703,451,68,13],
|
||||
["p1",1,"op","chess_char_5_19_b",2,"uniequip_002_mlynar",0,0,57,1,144856,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],
|
||||
["p1",5,"op","chess_char_5_15_b",1,"uniequip_002_thorn2",761.83,1,65,2,347988,3266,8910,106,15],
|
||||
["p1",6,"op","chess_char_5_20_b",2,"uniequip_002_aglina",601.22,1,64,0,74511,10416,444,39,4],
|
||||
["p1",7,"op","chess_char_5_21_b",1,"uniequip_002_sntlla",0,0,19,0,78150,3367,24,135,4],
|
||||
["p1",8,"op","chess_char_5_22_b",1,"uniequip_002_nymph",1093.46,1,69,2,86709,2593,464,31,11],
|
||||
["p1",9,"op","chess_char_5_23_b",1,"uniequip_002_reckpr",0,0,59,0,0,4410,18864,34,3],
|
||||
["p1",10,"op","chess_char_4_02_b",2,"uniequip_002_mostma",0,0,15,1,91518,3433,24,44,2],
|
||||
["p2",11,"op","chess_char_4_11_b",1,"uniequip_002_cathy",0,0,55,0,0,6776,33,0,1],
|
||||
["p2",12,"op","chess_char_4_04_b",1,"uniequip_002_ines",2149,1,72,0,160850,6885,116,158,7],
|
||||
["p2",13,"op","chess_char_4_07_b",1,"uniequip_002_bpipe",0,0,68,0,25917,7233,84,32,8],
|
||||
["p2",14,"op","chess_char_4_16_b",2,"uniequip_002_texas2",0,0,66,3,171812,20720,1824,108,14],
|
||||
["p2",15,"op","chess_char_4_09_b",1,"uniequip_002_mizuki",0,0,60,0,208060,6129,269,46,4],
|
||||
["p2",16,"op","chess_char_4_06_b",1,"uniequip_002_kroos2",0,0,61,0,117319,3470,348,113,2],
|
||||
["p2",17,"op","chess_char_4_10_b",1,"uniequip_002_aroma",0,0,14,0,0,2988,119,0,0],
|
||||
["p2",18,"op","chess_char_4_12_b",2,"uniequip_002_glady",0,0,20,0,61353,4837,2395,67,4],
|
||||
["p2",19,"op","chess_char_4_13_b",1,"uniequip_002_gnosis",1543.48,1,70,0,59776,3172,737,61,19],
|
||||
["p2",20,"op","chess_char_4_14_b",1,"uniequip_002_lionhd",1144.47,1,71,1,157265,2572,464,69,13],
|
||||
["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,1913,200612],"enemy_1438_dspred":[10,5,5,22724,648434],"enemy_1521_dslily":[1,0,0,93299,798117]},
|
||||
"hooks": [1,66,6000,1002,1068,2527,2646,4783,54,61,108,107,10,27478,1110,16,15,5,1,57,0,24,2],
|
||||
"events": {"atk":1226,"deploy":51,"die":56,"dmg":2639,"engage":17,"fx":653,"heal":160,"leak":5,"skill":215,"spawn":37,"status":755},
|
||||
"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},
|
||||
"fx": {
|
||||
"aoe": 21,
|
||||
"appear": 9,
|
||||
"blink": 2,
|
||||
"aoe": 20,
|
||||
"appear": 5,
|
||||
"blink": 6,
|
||||
"burst": 24,
|
||||
"charge": 9,
|
||||
"counter": 10,
|
||||
"crit": 44,
|
||||
"charge": 8,
|
||||
"counter": 16,
|
||||
"crit": 49,
|
||||
"dilemma": 4,
|
||||
"disappear": 9,
|
||||
"displace": 28,
|
||||
"disappear": 5,
|
||||
"displace": 27,
|
||||
"dodge": 2,
|
||||
"explosion": 13,
|
||||
"frostNova": 16,
|
||||
"frostNova": 19,
|
||||
"grow": 1,
|
||||
"iceSpike": 88,
|
||||
"iceSpike": 106,
|
||||
"overclock": 1,
|
||||
"pull": 4,
|
||||
"quadShot": 2,
|
||||
"ripple": 9,
|
||||
"rockfall": 11,
|
||||
"sentry": 4,
|
||||
"sermon": 1,
|
||||
"shadowWeave": 5,
|
||||
"shield": 3,
|
||||
"ripple": 14,
|
||||
"rockfall": 17,
|
||||
"sentry": 3,
|
||||
"sermon": 2,
|
||||
"shadowWeave": 4,
|
||||
"shield": 5,
|
||||
"soul": 3,
|
||||
"sp": 9,
|
||||
"stealth": 6,
|
||||
"swordRain": 40,
|
||||
"swordStorm": 6,
|
||||
"sp": 8,
|
||||
"stealth": 7,
|
||||
"swordRain": 103,
|
||||
"swordStorm": 14,
|
||||
"tentacle": 6,
|
||||
"tide": 5,
|
||||
"tornado": 4,
|
||||
"tornadoPulse": 20,
|
||||
"weightless": 4,
|
||||
"zone": 230
|
||||
"zone": 261
|
||||
},
|
||||
"snaps": "9d889e0e f29df90d 7a4bf6fc 19fe1302 bbe35359 e3aae426 3f978616 3d9f6e1d dcc49f9b e2e26bac eaf0159e 0d0a2271 04949e73 baad20e5 dca9ced6 a4351d0b b4846197 afc80a44 a6e80893 96d194a3"
|
||||
"snaps": "f65be30a 3fab4736 85e2bb50 91bfa19d 93214291 4b83b01b 615be497 b793dacf d713f4bf a63a221d c2db01e9 0546ff9b 17661f26 edf65cc8 addd19b1 59530186 37cddc6b 2c477685 7e246006 61595031"
|
||||
},
|
||||
"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",
|
||||
@@ -514,99 +543,103 @@
|
||||
"round": 14,
|
||||
"seed": 2302764647,
|
||||
"waveId": "act2autochess_h07_05",
|
||||
"time": 116.4,
|
||||
"ticks": 3492,
|
||||
"time": 159.97,
|
||||
"ticks": 4799,
|
||||
"reason": "cleared",
|
||||
"killed": 17,
|
||||
"total": 17,
|
||||
"killed": 23,
|
||||
"total": 23,
|
||||
"unspawned": 0,
|
||||
"bossHpLeft": 0,
|
||||
"rngDraws": 957,
|
||||
"rngDraws": 1140,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {
|
||||
"p1": {"killed":17,"total":17,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":999785,"bossDmg":756103,"heal":20375,"deaths":2,"layerGains":{}},
|
||||
"p2": {"killed":0,"total":0,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":1020000,"bossDmg":803897,"heal":61815,"deaths":3,"layerGains":{}}
|
||||
"p1": {"killed":23,"total":23,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":1078355,"bossDmg":854910,"heal":22023,"deaths":2,"layerGains":{}},
|
||||
"p2": {"killed":0,"total":0,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":1001429,"bossDmg":705090,"heal":86289,"deaths":3,"layerGains":{}}
|
||||
},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_6_03_b",2,"uniequip_002_yu",7216.72,1,7,0,54707,5937,9130,20,2],
|
||||
["p1",2,"op","chess_char_6_06_b",2,"uniequip_002_pepe",1074.06,1,12,0,46186,6044,294,16,2],
|
||||
["p1",3,"op","chess_char_6_07_b",2,"uniequip_002_siege2",3688.8,1,14,0,57400,4698,189,27,2],
|
||||
["p1",4,"op","chess_char_6_01_b",2,"uniequip_002_lemuen",1487.68,1,1,3,432902,4386,1760,36,3],
|
||||
["p1",5,"op","chess_char_6_02_b",2,"uniequip_002_sbell2",2520.63,1,16,1,76617,192,0,17,2],
|
||||
["p1",6,"op","chess_char_6_04_b",2,"uniequip_002_skadi2",1769.09,1,3,0,12934,9173,717,0,3],
|
||||
["p1",7,"op","chess_char_6_05_b",2,"uniequip_002_pasngr",1880.37,1,18,3,109704,1707,478,9,6],
|
||||
["p1",8,"op","chess_char_6_08_b",2,"uniequip_002_reed2",0,0,5,0,52484,4602,6914,33,2],
|
||||
["p1",9,"op","chess_char_6_09_b",0,"uniequip_002_cello",1723.89,1,20,2,113889,4068,505,20,20],
|
||||
["p1",10,"op","chess_char_6_11_b",2,"uniequip_002_mlyss",0,0,9,0,31419,2968,195,44,2],
|
||||
["p1",1,"op","chess_char_6_03_b",2,"uniequip_002_yu",3430,1,7,1,53498,8311,12460,26,2],
|
||||
["p1",2,"op","chess_char_6_06_b",2,"uniequip_002_pepe",2939,1,12,0,61955,3891,0,19,2],
|
||||
["p1",3,"op","chess_char_6_07_b",2,"uniequip_002_siege2",3101,1,14,0,91917,10020,129,42,2],
|
||||
["p1",4,"op","chess_char_6_01_b",2,"uniequip_002_lemuen",1470,1,68,1,210159,1691,0,29,2],
|
||||
["p1",5,"op","chess_char_6_02_b",2,"uniequip_002_sbell2",1933,1,16,1,136389,1672,0,33,2],
|
||||
["p1",6,"op","chess_char_6_04_b",2,"uniequip_002_skadi2",1598,1,69,0,8143,4362,61,0,3],
|
||||
["p1",7,"op","chess_char_6_05_b",2,"uniequip_002_pasngr",1442,1,18,2,182005,4889,826,17,8],
|
||||
["p1",8,"op","chess_char_6_08_b",2,"uniequip_002_reed2",1668,1,5,0,66889,2036,6709,54,3],
|
||||
["p1",9,"op","chess_char_6_09_b",0,"uniequip_002_cello",1322,1,20,2,161885,5631,862,30,30],
|
||||
["p1",10,"op","chess_char_6_11_b",2,"uniequip_002_mlyss",1893,1,9,1,71696,4482,0,130,4],
|
||||
["p1",11,"token","token_10017_skadi2_dedant",null,null,130.4,0,22,0,0,0,0,0,null],
|
||||
["p1",12,"token","token_10030_mlyss_wtrman",null,null,0,0,10,0,8925,2566,195,17,1],
|
||||
["p2",13,"op","chess_char_6_15_b",2,"uniequip_002_qiubai",0,0,42,2,260273,13743,0,91,3],
|
||||
["p2",14,"op","chess_char_6_19_b",2,"uniequip_002_blkkgt",2873.29,1,13,0,157481,6073,0,44,3],
|
||||
["p2",15,"op","chess_char_5_01_b",1,"uniequip_002_excu2",0,0,15,0,43092,3945,1631,40,1],
|
||||
["p2",16,"op","chess_char_6_17_b",2,"uniequip_002_nearl2",6089.82,1,55,2,138155,15493,0,43,3],
|
||||
["p2",17,"op","chess_char_6_12_b",1,"uniequip_002_rosmon",5503.36,1,2,1,209692,1801,1375,27,2],
|
||||
["p2",18,"op","chess_char_6_13_b",1,"uniequip_002_angel2",0,0,17,1,61810,8849,2844,8,1],
|
||||
["p2",19,"op","chess_char_6_14_b",2,"uniequip_002_lumen",1710.2,1,4,0,0,1532,10285,13,1],
|
||||
["p2",20,"op","chess_char_6_16_b",2,"uniequip_002_halo2",1876.46,1,19,2,24349,1047,0,38,2],
|
||||
["p2",21,"op","chess_char_6_18_b",2,"uniequip_002_whitw2",1125.01,1,6,1,110394,2111,0,0,2],
|
||||
["p2",22,"op","chess_char_6_20_b",2,"uniequip_002_agoat2",1970.34,1,21,0,0,3202,45680,36,2],
|
||||
["p1",12,"token","token_10030_mlyss_wtrman",null,null,0,0,10,0,10254,1668,0,20,1],
|
||||
["p2",13,"op","chess_char_6_15_b",2,"uniequip_002_qiubai",3117.59,1,74,6,320376,24405,0,103,5],
|
||||
["p2",14,"op","chess_char_6_19_b",2,"uniequip_002_blkkgt",2767,1,13,0,114213,9139,0,33,3],
|
||||
["p2",15,"op","chess_char_5_01_b",1,"uniequip_002_excu2",0,0,15,0,16826,3744,840,18,1],
|
||||
["p2",16,"op","chess_char_6_17_b",2,"uniequip_002_nearl2",5928.45,1,71,4,184426,11128,0,60,3],
|
||||
["p2",17,"op","chess_char_6_12_b",1,"uniequip_002_rosmon",5051.9,1,2,3,191473,2701,2473,25,2],
|
||||
["p2",18,"op","chess_char_6_13_b",1,"uniequip_002_angel2",3765.5,1,17,1,36144,9714,1669,8,1],
|
||||
["p2",19,"op","chess_char_6_14_b",2,"uniequip_002_lumen",1899,1,4,0,0,4530,14528,22,1],
|
||||
["p2",20,"op","chess_char_6_16_b",2,"uniequip_002_halo2",1554.12,1,19,1,22747,3140,0,37,3],
|
||||
["p2",21,"op","chess_char_6_18_b",2,"uniequip_002_whitw2",1541,1,66,0,100465,1541,0,14,2],
|
||||
["p2",22,"op","chess_char_6_20_b",2,"uniequip_002_agoat2",1631.88,1,21,0,0,2617,66779,48,2],
|
||||
["p2","~1","token","token_10019_nearl2_sword",null,null,1468.72,0,32,0,7863,6355,0,11,null],
|
||||
["p1","~1","token","token_10030_mlyss_wtrman",null,null,2175.07,0,36,0,2618,0,0,7,null],
|
||||
["p1","~1","token","token_10040_siege2_vlion",null,null,3173.37,0,39,0,0,1078,0,0,null],
|
||||
["p2","~2","token","token_10019_nearl2_sword",null,null,5622.56,0,46,0,0,857,0,0,null],
|
||||
["p1","~1","token","token_10017_skadi2_dedant",null,null,100,0,47,0,0,0,0,0,null],
|
||||
["p1","~2","token","token_10040_siege2_vlion",null,null,4677.04,1,57,0,0,539,0,0,null],
|
||||
["p2","~3","token","token_10019_nearl2_sword",null,null,7087.59,1,58,0,6892,736,0,0,null]
|
||||
["p1","~1","token","token_10030_mlyss_wtrman",null,null,2175.07,0,36,0,3496,0,0,10,null],
|
||||
["p1","~1","token","token_10040_siege2_vlion",null,null,2883.16,0,40,0,475,1239,0,1,null],
|
||||
["p2","~2","token","token_10019_nearl2_sword",null,null,0,0,46,0,5,6000,0,10,null],
|
||||
["p1","~1","token","token_10017_skadi2_dedant",null,null,100,0,50,0,0,0,0,0,null],
|
||||
["p1","~2","token","token_10030_mlyss_wtrman",null,null,1267.96,1,58,1,12448,2876,976,23,1],
|
||||
["p2","~3","token","token_10019_nearl2_sword",null,null,7087.59,0,61,0,6892,736,0,0,null],
|
||||
["p1","~2","token","token_10040_siege2_vlion",null,null,2158.7,0,63,0,1900,3057,0,4,null],
|
||||
["p1","~3","token","token_10030_mlyss_wtrman",null,null,1668,1,67,0,5246,0,0,14,null],
|
||||
["p1","~2","token","token_10017_skadi2_dedant",null,null,100,1,70,0,0,0,0,0,null]
|
||||
],
|
||||
"enemies": {
|
||||
"enemy_1010_demon_2": [2,2,0,3615,128995],
|
||||
"enemy_2009_csaudc": [4,4,0,2146,137594],
|
||||
"enemy_2010_csdcr": [2,2,0,4710,103196],
|
||||
"enemy_2016_csphtm": [2,2,0,94164,1560000],
|
||||
"enemy_2017_csphts": [9,9,0,88,90000]
|
||||
"enemy_2009_csaudc": [4,4,0,2382,137594],
|
||||
"enemy_2010_csdcr": [2,2,0,5808,103196],
|
||||
"enemy_2016_csphtm": [2,2,0,119394,1560000],
|
||||
"enemy_2017_csphts": [15,15,0,368,150000]
|
||||
},
|
||||
"hooks": [1,56,3492,654,654,1833,2142,3194,25,39,65,55,50,29032,1203,31,19,0,1,23,0,16,66],
|
||||
"events": {"atk":802,"deploy":37,"die":39,"dmg":1979,"engage":19,"fx":640,"heal":383,"skill":120,"spawn":48,"status":568},
|
||||
"hooks": [1,72,4799,936,936,2277,2696,2622,32,50,83,75,28,34452,1423,41,25,0,1,33,0,21,102],
|
||||
"events": {"atk":1185,"deploy":47,"die":50,"dmg":2489,"engage":25,"fx":655,"heal":520,"skill":158,"spawn":57,"status":697},
|
||||
"fx": {
|
||||
"airstrike": 18,
|
||||
"blink": 17,
|
||||
"bombard": 27,
|
||||
"bombardShell": 27,
|
||||
"burst": 16,
|
||||
"cleanse": 1,
|
||||
"copy": 1,
|
||||
"dodge": 66,
|
||||
"dp": 2,
|
||||
"drone": 202,
|
||||
"droneLock": 8,
|
||||
"airstrike": 9,
|
||||
"blink": 26,
|
||||
"bombard": 9,
|
||||
"bombardShell": 9,
|
||||
"burst": 21,
|
||||
"cleanse": 2,
|
||||
"copy": 2,
|
||||
"dodge": 102,
|
||||
"dp": 4,
|
||||
"drone": 165,
|
||||
"droneLock": 6,
|
||||
"drones": 2,
|
||||
"emergency": 1,
|
||||
"explode": 24,
|
||||
"extraAttack": 13,
|
||||
"emergency": 2,
|
||||
"explode": 34,
|
||||
"extraAttack": 4,
|
||||
"finale": 3,
|
||||
"firewall": 2,
|
||||
"garrisonGrant": 1,
|
||||
"lightning": 55,
|
||||
"link": 3,
|
||||
"lock": 27,
|
||||
"lightning": 88,
|
||||
"link": 4,
|
||||
"lock": 11,
|
||||
"lure": 2,
|
||||
"palsy": 1,
|
||||
"radiantSword": 3,
|
||||
"scorchBurst": 3,
|
||||
"shield": 14,
|
||||
"shield": 15,
|
||||
"slash": 33,
|
||||
"snow": 22,
|
||||
"split": 1,
|
||||
"snow": 30,
|
||||
"split": 2,
|
||||
"steal": 1,
|
||||
"storm": 6,
|
||||
"storm": 8,
|
||||
"strike": 3,
|
||||
"summon": 14,
|
||||
"sunBurst": 5,
|
||||
"talent": 4,
|
||||
"telegraph": 2,
|
||||
"summon": 20,
|
||||
"sunBurst": 6,
|
||||
"talent": 5,
|
||||
"telegraph": 8,
|
||||
"tide": 3,
|
||||
"wanted": 8
|
||||
"wanted": 6
|
||||
},
|
||||
"snaps": "eca813c6 f271e40a c26e5584 d73b51c9 a7c760e5 818a39be 850539df a8a1d78c 1c2b94fb 61f626e7 15b5d45a 89f18974"
|
||||
"snaps": "eca813c6 f271e40a c26e5584 816c07e5 7f7c4cb1 d37721ad d85cc2d4 218f40ad 9eb56a3f e8084223 739d5ee7 bc9421b3 9d553bd1 a5a6f014 8644b31a 3d2e2650"
|
||||
},
|
||||
"boss-boss_5-solo": {
|
||||
"about": "卢西恩,“猩红血钻” solo pool 780000: chess_char_5_08_b chess_char_5_11_b chess_char_5_05_b chess_char_5_06_b chess_char_5_13_b chess_char_5_07_b chess_char_5_02_b chess_char_5_03_b chess_char_5_10_b chess_char_5_12_b",
|
||||
@@ -667,62 +700,62 @@
|
||||
"time": 200,
|
||||
"ticks": 6000,
|
||||
"reason": "forced",
|
||||
"killed": 4,
|
||||
"killed": 5,
|
||||
"total": 6,
|
||||
"unspawned": 0,
|
||||
"bossHpLeft": 6660590,
|
||||
"rngDraws": 559,
|
||||
"bossHpLeft": 6937575,
|
||||
"rngDraws": 481,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {
|
||||
"p1": {"killed":4,"total":6,"perfect":false,"leaks":1,"leaksUncounted":0,"coins":0,"dmg":1051226,"bossDmg":642651,"heal":3896,"deaths":5,"layerGains":{}},
|
||||
"p2": {"killed":0,"total":0,"perfect":false,"leaks":1,"leaksUncounted":0,"coins":0,"dmg":1151422,"bossDmg":656759,"heal":1055,"deaths":12,"layerGains":{}}
|
||||
"p1": {"killed":5,"total":6,"perfect":false,"leaks":1,"leaksUncounted":0,"coins":0,"dmg":962744,"bossDmg":480128,"heal":1353,"deaths":4,"layerGains":{}},
|
||||
"p2": {"killed":0,"total":0,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":1105264,"bossDmg":542298,"heal":401,"deaths":15,"layerGains":{}}
|
||||
},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_5_19_b",2,"uniequip_002_mlynar",3907,1,3,2,107043,0,0,26,3],
|
||||
["p1",1,"op","chess_char_5_19_b",2,"uniequip_002_mlynar",3907,1,3,2,150079,0,0,34,2],
|
||||
["p1",2,"op","chess_char_4_01_b",2,"uniequip_002_rmixer",3537,1,1,0,0,0,0,0,0],
|
||||
["p1",3,"op","chess_char_5_14_b",1,"none",1994,1,5,0,38065,0,0,0,13],
|
||||
["p1",4,"op","chess_char_5_17_b",1,"uniequip_002_f12yin",4654.6,1,11,0,2464,0,0,3,1],
|
||||
["p1",5,"op","chess_char_5_15_b",1,"uniequip_002_thorn2",1170,1,7,2,332249,0,1482,73,12],
|
||||
["p1",6,"op","chess_char_5_20_b",2,"uniequip_002_aglina",1382,1,13,0,198299,0,0,75,6],
|
||||
["p1",7,"op","chess_char_5_21_b",1,"uniequip_002_sntlla",0,0,15,0,28901,1629,0,50,2],
|
||||
["p1",8,"op","chess_char_5_22_b",1,"uniequip_002_nymph",0,0,47,0,287701,3222,0,85,28],
|
||||
["p1",9,"op","chess_char_5_23_b",1,"uniequip_002_reckpr",0,0,49,0,2900,3220,2414,4,1],
|
||||
["p1",10,"op","chess_char_4_02_b",2,"uniequip_002_mostma",1695,1,9,0,53605,0,0,40,2],
|
||||
["p1",3,"op","chess_char_5_14_b",1,"none",1994,1,5,1,53410,0,0,0,15],
|
||||
["p1",4,"op","chess_char_5_17_b",1,"uniequip_002_f12yin",4654.6,1,11,0,0,0,0,0,1],
|
||||
["p1",5,"op","chess_char_5_15_b",1,"uniequip_002_thorn2",1170,1,7,1,288098,0,269,74,11],
|
||||
["p1",6,"op","chess_char_5_20_b",2,"uniequip_002_aglina",1382,1,13,0,199470,0,0,73,6],
|
||||
["p1",7,"op","chess_char_5_21_b",1,"uniequip_002_sntlla",1629,1,15,0,33233,0,0,49,2],
|
||||
["p1",8,"op","chess_char_5_22_b",1,"uniequip_002_nymph",0,0,47,0,181975,3222,0,53,16],
|
||||
["p1",9,"op","chess_char_5_23_b",1,"uniequip_002_reckpr",0,0,49,0,1934,4573,1083,1,1],
|
||||
["p1",10,"op","chess_char_4_02_b",2,"uniequip_002_mostma",1695,1,9,0,54545,0,0,41,2],
|
||||
["p2",11,"op","chess_char_4_11_b",1,"uniequip_002_cathy",2644,1,46,0,0,12182,281,0,1],
|
||||
["p2",12,"op","chess_char_4_04_b",1,"uniequip_002_ines",0,0,41,0,136097,9003,729,279,6],
|
||||
["p2",12,"op","chess_char_4_04_b",1,"uniequip_002_ines",0,0,53,0,132250,11795,83,210,5],
|
||||
["p2",13,"op","chess_char_4_07_b",1,"uniequip_002_bpipe",2383,1,6,0,0,0,0,0,0],
|
||||
["p2",14,"op","chess_char_4_16_b",2,"uniequip_002_texas2",1619,1,43,0,57804,9849,44,187,5],
|
||||
["p2",15,"op","chess_char_4_09_b",1,"uniequip_002_mizuki",2777.6,1,14,0,239542,0,0,118,6],
|
||||
["p2",16,"op","chess_char_4_06_b",1,"uniequip_002_kroos2",1561,1,8,0,456796,0,0,132,2],
|
||||
["p2",14,"op","chess_char_4_16_b",2,"uniequip_002_texas2",0,0,56,0,60073,10804,37,181,7],
|
||||
["p2",15,"op","chess_char_4_09_b",1,"uniequip_002_mizuki",2777.6,1,14,0,204305,0,0,117,6],
|
||||
["p2",16,"op","chess_char_4_06_b",1,"uniequip_002_kroos2",1561,1,8,1,383161,0,0,107,2],
|
||||
["p2",17,"op","chess_char_4_10_b",1,"uniequip_002_aroma",1664,1,12,0,0,0,0,0,0],
|
||||
["p2",18,"op","chess_char_4_12_b",2,"uniequip_002_glady",0,0,48,0,37231,4464,0,91,4],
|
||||
["p2",19,"op","chess_char_4_13_b",1,"uniequip_002_gnosis",0,0,44,0,120920,3978,0,113,27],
|
||||
["p2",20,"op","chess_char_4_14_b",1,"uniequip_002_lionhd",1626,1,52,0,103033,3252,0,33,6],
|
||||
["p2",18,"op","chess_char_4_12_b",2,"uniequip_002_glady",2232,1,48,0,70233,2232,0,102,4],
|
||||
["p2",19,"op","chess_char_4_13_b",1,"uniequip_002_gnosis",0,0,44,0,97692,3978,0,86,21],
|
||||
["p2",20,"op","chess_char_4_14_b",1,"uniequip_002_lionhd",0,0,45,0,157549,3252,0,49,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_10028_vtswd": [5,5,0,0,0],
|
||||
"enemy_10028_vtswd": [6,6,0,0,0],
|
||||
"enemy_10029_vtshld": [2,2,0,0,0],
|
||||
"enemy_10030_vtwand": [1,1,0,0,0],
|
||||
"enemy_10085_hllevi_2": [2,0,2,0,702625],
|
||||
"enemy_1010_demon": [4,4,0,15134,200612],
|
||||
"enemy_9032_aclionk": [1,0,0,35665,1299410]
|
||||
"enemy_10030_vtwand": [3,3,0,0,0],
|
||||
"enemy_10085_hllevi_2": [2,1,1,0,844970],
|
||||
"enemy_1010_demon": [4,4,0,12182,200612],
|
||||
"enemy_9032_aclionk": [1,0,0,39855,1022425]
|
||||
},
|
||||
"hooks": [1,50,6000,1291,1314,2325,2345,811,29,33,125,123,0,36836,1303,4,15,2,1,25,0,5,0],
|
||||
"events": {"atk":1354,"deploy":35,"die":31,"dmg":2324,"engage":14,"fx":616,"heal":20,"leak":2,"skill":248,"spawn":37,"status":889},
|
||||
"hooks": [1,55,6000,1156,1181,2148,2161,330,35,38,111,109,0,34074,1139,2,18,1,1,28,0,3,0],
|
||||
"events": {"atk":1239,"deploy":37,"die":37,"dmg":2090,"engage":13,"fx":582,"heal":3,"leak":1,"skill":220,"spawn":40,"status":950},
|
||||
"fx": {
|
||||
"aoe": 48,
|
||||
"aoe": 37,
|
||||
"appear": 4,
|
||||
"blink": 2,
|
||||
"burst": 5,
|
||||
"crit": 75,
|
||||
"burst": 3,
|
||||
"crit": 60,
|
||||
"dilemma": 6,
|
||||
"disappear": 4,
|
||||
"displace": 19,
|
||||
"equip": 9,
|
||||
"explosion": 6,
|
||||
"frostNova": 27,
|
||||
"equip": 14,
|
||||
"explosion": 9,
|
||||
"frostNova": 21,
|
||||
"garrisonGrant": 1,
|
||||
"iceSpike": 44,
|
||||
"overclock": 1,
|
||||
@@ -730,23 +763,23 @@
|
||||
"quadShot": 2,
|
||||
"revive": 2,
|
||||
"ripple": 18,
|
||||
"sentry": 3,
|
||||
"shadowWeave": 2,
|
||||
"sentry": 4,
|
||||
"shadowWeave": 4,
|
||||
"shield": 1,
|
||||
"soul": 5,
|
||||
"sp": 18,
|
||||
"stealth": 6,
|
||||
"soul": 3,
|
||||
"sp": 13,
|
||||
"stealth": 5,
|
||||
"sword": 4,
|
||||
"swordRain": 21,
|
||||
"swordStorm": 5,
|
||||
"telegraph": 14,
|
||||
"swordRain": 31,
|
||||
"swordStorm": 7,
|
||||
"telegraph": 18,
|
||||
"tornado": 4,
|
||||
"tornadoPulse": 20,
|
||||
"vest": 2,
|
||||
"weightless": 6,
|
||||
"zone": 228
|
||||
"zone": 209
|
||||
},
|
||||
"snaps": "5feb83ed f13ed3b4 56be9cfd 39b0aa8a e95d527f 3acb6fe4 5cf64994 3a284512 941757f8 a04e88b3 04d5b3e2 1390b339 3e94c413 ad43bd42 f1b1463c af767763 1630b47b 0444ec4e 3be9c125 022e8e64"
|
||||
"snaps": "9c6ce142 8a6dcc91 4f97bc5f 50bf0124 38b0c8c6 45c468a3 44e29257 4724879b 8c7622b1 5290f2f6 0bbfb1a6 51e0b266 c1f639dd 8c0da971 125f843e 3efd2bda fdec864d f9735dd3 51aa9170 3db9cfa4"
|
||||
},
|
||||
"boss-boss_6-solo": {
|
||||
"about": "阿利斯泰尔,帝国余晖 solo pool 3980000: 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",
|
||||
@@ -925,92 +958,94 @@
|
||||
"time": 200,
|
||||
"ticks": 6000,
|
||||
"reason": "forced",
|
||||
"killed": 13,
|
||||
"killed": 12,
|
||||
"total": 18,
|
||||
"unspawned": 0,
|
||||
"bossHpLeft": 12749411,
|
||||
"rngDraws": 469,
|
||||
"bossHpLeft": 12629621,
|
||||
"rngDraws": 468,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {
|
||||
"p1": {"killed":13,"total":18,"perfect":false,"leaks":2,"leaksUncounted":0,"coins":0,"dmg":1782144,"bossDmg":862264,"heal":34974,"deaths":19,"layerGains":{}},
|
||||
"p2": {"killed":0,"total":0,"perfect":false,"leaks":2,"leaksUncounted":0,"coins":0,"dmg":1063494,"bossDmg":787168,"heal":3526,"deaths":23,"layerGains":{}}
|
||||
"p1": {"killed":12,"total":18,"perfect":false,"leaks":3,"leaksUncounted":0,"coins":0,"dmg":1813792,"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",0,0,73,2,70060,30258,344,15,1],
|
||||
["p1",2,"op","chess_char_4_01_b",2,"uniequip_002_rmixer",5411.15,1,78,0,6068,12135,463,20,2],
|
||||
["p1",3,"op","chess_char_5_14_b",1,"none",0,0,82,0,47436,18275,3606,26,11],
|
||||
["p1",4,"op","chess_char_5_17_b",1,"uniequip_002_f12yin",5476,1,88,0,43232,18483,434,21,3],
|
||||
["p1",5,"op","chess_char_5_15_b",1,"uniequip_002_thorn2",161.56,1,79,2,719512,4898,9898,98,11],
|
||||
["p1",6,"op","chess_char_5_20_b",2,"uniequip_002_aglina",2764,1,93,1,69538,10605,41,18,2],
|
||||
["p1",7,"op","chess_char_5_21_b",1,"uniequip_002_sntlla",2053.18,1,83,1,288400,7730,9,2,1],
|
||||
["p1",8,"op","chess_char_5_22_b",1,"uniequip_002_nymph",1084.8,1,72,1,524208,5369,9,40,13],
|
||||
["p1",9,"op","chess_char_5_23_b",1,"uniequip_002_reckpr",3220,1,90,0,0,11772,20169,18,2],
|
||||
["p1",10,"op","chess_char_4_02_b",2,"uniequip_002_mostma",0,0,80,1,13692,10170,0,9,1],
|
||||
["p2",11,"op","chess_char_4_11_b",1,"uniequip_002_cathy",0,0,75,0,0,7525,137,0,2],
|
||||
["p2",12,"op","chess_char_4_04_b",1,"uniequip_002_ines",2149,1,84,2,27393,10756,5,74,5],
|
||||
["p2",13,"op","chess_char_4_07_b",1,"uniequip_002_bpipe",4170.25,1,92,1,15991,9948,1608,6,3],
|
||||
["p2",14,"op","chess_char_4_16_b",2,"uniequip_002_texas2",1619,1,87,0,78679,12401,119,22,8],
|
||||
["p2",15,"op","chess_char_4_09_b",1,"uniequip_002_mizuki",0,0,67,0,126046,8396,309,30,3],
|
||||
["p2",16,"op","chess_char_4_06_b",1,"uniequip_002_kroos2",0,0,71,1,301353,3122,0,77,1],
|
||||
["p2",17,"op","chess_char_4_10_b",1,"uniequip_002_aroma",0,0,20,0,52829,6922,264,53,2],
|
||||
["p2",18,"op","chess_char_4_12_b",2,"uniequip_002_glady",2232,1,86,0,42669,2582,350,30,3],
|
||||
["p2",19,"op","chess_char_4_13_b",1,"uniequip_002_gnosis",0,0,63,2,356112,4467,489,68,20],
|
||||
["p2",20,"op","chess_char_4_14_b",1,"uniequip_002_lionhd",0,0,64,1,62422,3497,245,25,4],
|
||||
["p1",1,"op","chess_char_5_19_b",2,"uniequip_002_mlynar",7814,1,87,2,99556,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",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],
|
||||
["p2",12,"op","chess_char_4_04_b",1,"uniequip_002_ines",2149,1,81,1,12100,12569,39,82,4],
|
||||
["p2",13,"op","chess_char_4_07_b",1,"uniequip_002_bpipe",0,0,60,1,16724,11556,3215,13,4],
|
||||
["p2",14,"op","chess_char_4_16_b",2,"uniequip_002_texas2",0,0,85,0,52687,10354,93,18,6],
|
||||
["p2",15,"op","chess_char_4_09_b",1,"uniequip_002_mizuki",0,0,63,1,136890,11467,404,44,5],
|
||||
["p2",16,"op","chess_char_4_06_b",1,"uniequip_002_kroos2",0,0,67,1,299704,3122,0,68,1],
|
||||
["p2",17,"op","chess_char_4_10_b",1,"uniequip_002_aroma",1664,1,84,0,61299,4658,245,63,3],
|
||||
["p2",18,"op","chess_char_4_12_b",2,"uniequip_002_glady",0,0,68,0,23874,6560,2096,11,1],
|
||||
["p2",19,"op","chess_char_4_13_b",1,"uniequip_002_gnosis",0,0,61,0,69433,3978,0,73,20],
|
||||
["p2",20,"op","chess_char_4_14_b",1,"uniequip_002_lionhd",0,0,62,2,433992,3341,89,57,11],
|
||||
["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_10027_vtsk": [6,1,4,138886,892170],
|
||||
"enemy_10027_vtsk": [6,1,3,119156,802040],
|
||||
"enemy_1005_yokai": [4,4,0,0,1600],
|
||||
"enemy_1229_darmy_2": [8,8,0,3486,294231],
|
||||
"enemy_9013_acstmk_2": [1,0,0,45577,1650589],
|
||||
"enemy_9014_acstma": [5,4,0,2385,30898],
|
||||
"enemy_9015_acstmb": [2,1,0,8977,5739],
|
||||
"enemy_9016_acstmr": [8,7,0,0,41]
|
||||
"enemy_1229_darmy_2": [8,7,1,4411,292434],
|
||||
"enemy_9013_acstmk_2": [1,0,0,46945,1770379],
|
||||
"enemy_9014_acstma": [5,4,0,4133,27092],
|
||||
"enemy_9015_acstmb": [3,2,0,8822,56064],
|
||||
"enemy_9016_acstmr": [8,7,0,0,38]
|
||||
},
|
||||
"hooks": [1,91,6000,753,753,2602,2727,3433,67,73,98,95,6,20855,903,13,34,4,1,71,0,4,11],
|
||||
"events": {"atk":855,"deploy":57,"die":69,"dmg":2724,"engage":17,"fx":566,"heal":95,"leak":4,"skill":193,"spawn":56,"status":571},
|
||||
"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},
|
||||
"fx": {
|
||||
"aoe": 37,
|
||||
"appear": 8,
|
||||
"aoe": 26,
|
||||
"appear": 9,
|
||||
"beam": 48,
|
||||
"blink": 13,
|
||||
"burst": 4,
|
||||
"charge": 9,
|
||||
"counter": 6,
|
||||
"crit": 44,
|
||||
"dilemma": 3,
|
||||
"disappear": 8,
|
||||
"dodge": 11,
|
||||
"burst": 6,
|
||||
"charge": 10,
|
||||
"counter": 5,
|
||||
"crit": 43,
|
||||
"dilemma": 5,
|
||||
"disappear": 9,
|
||||
"dodge": 12,
|
||||
"explode": 6,
|
||||
"explosion": 4,
|
||||
"explosion": 11,
|
||||
"frostNova": 20,
|
||||
"iceSpike": 2,
|
||||
"iceSpike": 3,
|
||||
"overclock": 2,
|
||||
"palsy": 1,
|
||||
"phase": 3,
|
||||
"pull": 2,
|
||||
"pull": 1,
|
||||
"quadShot": 1,
|
||||
"revive": 2,
|
||||
"ripple": 9,
|
||||
"sentry": 4,
|
||||
"sermon": 2,
|
||||
"sermon": 1,
|
||||
"shadowWeave": 8,
|
||||
"shell": 8,
|
||||
"shield": 4,
|
||||
"slippery": 2,
|
||||
"soul": 4,
|
||||
"sp": 9,
|
||||
"spGain": 2,
|
||||
"stealth": 5,
|
||||
"shield": 5,
|
||||
"slippery": 3,
|
||||
"soul": 5,
|
||||
"sp": 7,
|
||||
"spGain": 10,
|
||||
"stealth": 4,
|
||||
"summon": 4,
|
||||
"swordRain": 67,
|
||||
"swordStorm": 8,
|
||||
"swordRain": 37,
|
||||
"swordStorm": 6,
|
||||
"telegraph": 6,
|
||||
"tornado": 3,
|
||||
"tornadoPulse": 11,
|
||||
"tornado": 1,
|
||||
"tornadoPulse": 5,
|
||||
"weightless": 2,
|
||||
"zone": 184
|
||||
"zone": 178
|
||||
},
|
||||
"snaps": "1b4d1c90 5e89ae3a 18b0277b 718ea4d9 fb14ee3f 2c5d7b5a 90a9e918 535d6535 ff46bb00 d6a87ebe a53bce20 63043c57 e1656d7b 7fb55cb8 8d7c7ef0 ced6863b 72e4c7b9 574e2998 fcaf465c 0ac59845"
|
||||
"snaps": "1b4d1c90 fb246339 f1dd6c3a f6d6e05e 52ebafed 068e9a5e 29f24601 932c2a97 8f79d53e 376fa541 2d8ce13d e0ab9b09 87adcf7a a8ebe0bd 0714a18a 50636ff0 5ed52282 d05808ac 964062c6 c6a3ead9"
|
||||
},
|
||||
"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",
|
||||
@@ -1241,63 +1276,61 @@
|
||||
"killed": 12,
|
||||
"total": 12,
|
||||
"unspawned": 0,
|
||||
"bossHpLeft": 14505955,
|
||||
"rngDraws": 1001,
|
||||
"bossHpLeft": 14515498,
|
||||
"rngDraws": 988,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {
|
||||
"p1": {"killed":12,"total":12,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":358279,"bossDmg":203660,"heal":4886,"deaths":1,"layerGains":{}},
|
||||
"p2": {"killed":0,"total":0,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":670269,"bossDmg":490385,"heal":8820,"deaths":8,"layerGains":{}}
|
||||
"p1": {"killed":12,"total":12,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":394375,"bossDmg":227133,"heal":12075,"deaths":0,"layerGains":{}},
|
||||
"p2": {"killed":0,"total":0,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":624631,"bossDmg":457370,"heal":8804,"deaths":8,"layerGains":{}}
|
||||
},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_5_19_b",2,"uniequip_002_mlynar",3907,1,5,0,0,0,0,0,0],
|
||||
["p1",2,"op","chess_char_4_01_b",2,"uniequip_002_rmixer",3537,1,9,0,0,0,0,0,0],
|
||||
["p1",3,"op","chess_char_5_14_b",1,"none",3489.5,1,15,0,0,0,0,0,0],
|
||||
["p1",4,"op","chess_char_5_17_b",1,"uniequip_002_f12yin",2738,1,17,1,24417,1893,995,40,1],
|
||||
["p1",5,"op","chess_char_5_15_b",1,"uniequip_002_thorn2",1989,1,11,2,129281,0,2712,20,4],
|
||||
["p1",6,"op","chess_char_5_20_b",2,"uniequip_002_aglina",1382,1,19,1,62301,949,20,64,6],
|
||||
["p1",7,"op","chess_char_5_21_b",1,"uniequip_002_sntlla",1629,1,51,2,105321,2848,231,226,6],
|
||||
["p1",4,"op","chess_char_5_17_b",1,"uniequip_002_f12yin",2738,1,17,2,18626,5825,2147,41,1],
|
||||
["p1",5,"op","chess_char_5_15_b",1,"uniequip_002_thorn2",1989,1,11,2,172080,0,8481,23,6],
|
||||
["p1",6,"op","chess_char_5_20_b",2,"uniequip_002_aglina",1382,1,19,2,60569,981,0,64,6],
|
||||
["p1",7,"op","chess_char_5_21_b",1,"uniequip_002_sntlla",1629,1,21,0,97740,5270,467,222,6],
|
||||
["p1",8,"op","chess_char_5_22_b",1,"uniequip_002_nymph",1611,1,3,0,0,0,0,0,0],
|
||||
["p1",9,"op","chess_char_5_23_b",1,"uniequip_002_reckpr",1610,1,7,0,0,0,929,2,1],
|
||||
["p1",10,"op","chess_char_4_02_b",2,"uniequip_002_mostma",1695,1,13,0,36960,0,0,30,3],
|
||||
["p1",9,"op","chess_char_5_23_b",1,"uniequip_002_reckpr",1610,1,7,0,0,0,981,1,1],
|
||||
["p1",10,"op","chess_char_4_02_b",2,"uniequip_002_mostma",1695,1,13,0,45360,0,0,30,3],
|
||||
["p2",11,"op","chess_char_4_11_b",1,"uniequip_002_cathy",2644,1,6,0,0,0,0,0,0],
|
||||
["p2",12,"op","chess_char_4_04_b",1,"uniequip_002_ines",2149,1,54,0,113346,5807,112,174,5],
|
||||
["p2",13,"op","chess_char_4_07_b",1,"uniequip_002_bpipe",0,0,49,0,4,5859,855,2,2],
|
||||
["p2",14,"op","chess_char_4_16_b",2,"uniequip_002_texas2",1619,1,50,0,42778,7059,344,190,5],
|
||||
["p2",15,"op","chess_char_4_09_b",1,"uniequip_002_mizuki",1268.93,1,18,5,204995,2254,745,84,5],
|
||||
["p2",16,"op","chess_char_4_06_b",1,"uniequip_002_kroos2",1561,1,12,3,160077,0,0,271,4],
|
||||
["p2",17,"op","chess_char_4_10_b",1,"uniequip_002_aroma",1449.33,1,20,0,9408,888,673,8,2],
|
||||
["p2",18,"op","chess_char_4_12_b",2,"uniequip_002_glady",1532.27,1,22,0,50178,6810,6090,122,4],
|
||||
["p2",19,"op","chess_char_4_13_b",1,"uniequip_002_gnosis",1989,1,4,1,30075,0,0,34,11],
|
||||
["p2",20,"op","chess_char_4_14_b",1,"uniequip_002_lionhd",1626,1,8,1,59410,0,0,24,6],
|
||||
["p2",12,"op","chess_char_4_04_b",1,"uniequip_002_ines",2149,1,52,0,113544,5807,112,174,5],
|
||||
["p2",13,"op","chess_char_4_07_b",1,"uniequip_002_bpipe",0,0,49,0,0,5859,855,0,0],
|
||||
["p2",14,"op","chess_char_4_16_b",2,"uniequip_002_texas2",1619,1,44,1,27238,4358,68,23,5],
|
||||
["p2",15,"op","chess_char_4_09_b",1,"uniequip_002_mizuki",1135.93,1,18,5,203469,2387,745,84,5],
|
||||
["p2",16,"op","chess_char_4_06_b",1,"uniequip_002_kroos2",1561,1,12,2,158875,0,0,271,4],
|
||||
["p2",17,"op","chess_char_4_10_b",1,"uniequip_002_aroma",0,0,20,1,11085,2337,673,8,2],
|
||||
["p2",18,"op","chess_char_4_12_b",2,"uniequip_002_glady",1142.27,1,22,0,50178,7440,6350,122,5],
|
||||
["p2",19,"op","chess_char_4_13_b",1,"uniequip_002_gnosis",1989,1,4,1,13350,0,0,20,7],
|
||||
["p2",20,"op","chess_char_4_14_b",1,"uniequip_002_lionhd",1626,1,8,0,46893,0,0,20,5],
|
||||
["p2",21,"token","token_10041_cathy_catsld",null,null,100,1,23,0,0,0,0,0,null],
|
||||
["p2",22,"token","token_10041_cathy_catsld",null,null,100,1,24,0,0,0,0,0,null],
|
||||
["-","~1","device","trap_1105_accrate",null,null,100,1,1,0,0,0,0,0,null],
|
||||
["-","~2","device","trap_1105_accrate",null,null,100,1,2,0,0,0,0,0,null]
|
||||
],
|
||||
"enemies": {
|
||||
"enemy_1402_tgshd_2": [2,2,0,6652,173864],
|
||||
"enemy_9010_acpupp": [2,2,0,1619,160520],
|
||||
"enemy_9021_acduml_2": [1,0,0,0,694045],
|
||||
"enemy_9022_acdumm": [1,0,0,877,0],
|
||||
"enemy_9023_acdums": [12,12,0,19360,120]
|
||||
"enemy_1402_tgshd_2": [2,2,0,6854,173864],
|
||||
"enemy_9010_acpupp": [2,2,0,6188,160520],
|
||||
"enemy_9021_acduml_2": [1,0,0,343,684502],
|
||||
"enemy_9022_acdumm": [1,0,0,453,0],
|
||||
"enemy_9023_acdums": [12,12,0,20566,120]
|
||||
},
|
||||
"hooks": [1,52,6000,1110,1260,2516,2697,5451,25,27,65,62,0,30164,1499,5,18,0,1,27,0,7,1],
|
||||
"events": {"atk":1215,"deploy":32,"die":27,"dmg":2691,"engage":14,"fx":1023,"heal":31,"skill":127,"spawn":42,"status":602},
|
||||
"hooks": [1,50,6000,941,1070,2359,2526,5809,25,26,61,57,0,29827,1409,6,18,0,1,27,0,7,0],
|
||||
"events": {"atk":1039,"deploy":30,"die":26,"dmg":2515,"engage":13,"fx":1003,"heal":80,"skill":118,"spawn":42,"status":551},
|
||||
"fx": {
|
||||
"beam": 13,
|
||||
"blink": 2,
|
||||
"burst": 7,
|
||||
"charge": 2,
|
||||
"crit": 135,
|
||||
"crit": 131,
|
||||
"dilemma": 5,
|
||||
"dodge": 1,
|
||||
"ember": 2,
|
||||
"explode": 195,
|
||||
"explosion": 6,
|
||||
"expose": 200,
|
||||
"frostNova": 11,
|
||||
"explode": 191,
|
||||
"explosion": 5,
|
||||
"expose": 197,
|
||||
"frostNova": 7,
|
||||
"garrisonGrant": 1,
|
||||
"iceSpike": 190,
|
||||
"iceSpike": 174,
|
||||
"levitate": 5,
|
||||
"phase": 33,
|
||||
"pull": 4,
|
||||
@@ -1308,18 +1341,19 @@
|
||||
"shield": 1,
|
||||
"shieldBreak": 1,
|
||||
"slippery": 2,
|
||||
"sp": 2,
|
||||
"splash": 2,
|
||||
"stealth": 5,
|
||||
"summon": 8,
|
||||
"swordRain": 37,
|
||||
"swordRain": 11,
|
||||
"swordStorm": 5,
|
||||
"telegraph": 2,
|
||||
"tornado": 4,
|
||||
"tornado": 5,
|
||||
"tornadoPulse": 20,
|
||||
"weightless": 6,
|
||||
"zone": 76
|
||||
"zone": 114
|
||||
},
|
||||
"snaps": "069c7e32 c7501279 b8a16379 183de18f 603028d5 6047bb6b 7dcf828f 66417d52 af439cf5 e7cd47f0 519c8da9 23a57b78 b6a29491 1afdf228 1f1c2f89 87c303a4 5772dcce 1ee11042 d00caaad 4e17c1ae"
|
||||
"snaps": "49432b5c cddad0da 3993b67f fe18e827 e325aa6f e3507596 6dae8854 9ec756b3 f6992ec7 719c1d70 000a8c83 e21724b6 048a2272 e503c179 6ee22b0f 01d2c4eb e4be8103 ce55c589 e0d4a7eb 826b43d7"
|
||||
},
|
||||
"hidden-boss_10-solo": {
|
||||
"about": "假想敌:管 solo pool 7600000: 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",
|
||||
|
||||
+23
-23
@@ -99,7 +99,7 @@
|
||||
"combat": "client",
|
||||
"boost": null,
|
||||
"setup": {"stageId":"act1autochess_m03","bossId":"boss_5","hiddenBossId":"boss_8","factions":["TIMES","DOT","INVISIBLE"]},
|
||||
"end": {"victory":true,"roundsPassed":15,"hiddenReached":true,"hiddenCleared":true,"reason":"victory","teamLp":26,"bossPoolLeft":0,"virtualMs":112800},
|
||||
"end": {"victory":true,"roundsPassed":15,"hiddenReached":true,"hiddenCleared":true,"reason":"victory","teamLp":27,"bossPoolLeft":0,"virtualMs":112800},
|
||||
"rng": {"setup":25,"shop":233,"waves":0,"draft":10,"bots":8923,"meta":6},
|
||||
"errors": {"engine":0,"logged":0,"sim":0,"dispatcher":0},
|
||||
"rounds": [
|
||||
@@ -137,11 +137,11 @@
|
||||
},
|
||||
{
|
||||
"round": 12,
|
||||
"ai_0": [1,26,12,0,0,6,8,"95e59cfc",213,"arcaneShip 1/14, kazimierzShip 0/10, kjeragShip 0/2, preciShip 2/54, sargonShip 0/8, siracusaShip 1/102, soloShip 1/3, steadShip 0/2, suntShip 1/0, swiftShip 1/40",30,31,1,109]
|
||||
"ai_0": [1,27,12,0,0,6,8,"95e59cfc",217,"arcaneShip 1/14, kazimierzShip 0/10, kjeragShip 0/2, preciShip 2/54, sargonShip 0/8, siracusaShip 1/106, soloShip 1/3, steadShip 0/2, suntShip 1/0, swiftShip 1/40",31,31,0,109]
|
||||
},
|
||||
{
|
||||
"round": 13,
|
||||
"ai_0": [1,26,12,0,0,6,8,"168e12ee",335,"arcaneShip 2/18, kazimierzShip 0/10, kjeragShip 0/2, preciShip 2/59, sargonShip 0/8, siracusaShip 1/210, soloShip 1/3, steadShip 0/2, suntShip 1/0, swiftShip 1/45",115,115,0,121]
|
||||
"ai_0": [1,27,12,0,0,6,8,"168e12ee",339,"arcaneShip 2/18, kazimierzShip 0/10, kjeragShip 0/2, preciShip 2/59, sargonShip 0/8, siracusaShip 1/214, soloShip 1/3, steadShip 0/2, suntShip 1/0, swiftShip 1/45",115,115,0,121]
|
||||
}
|
||||
],
|
||||
"players": {
|
||||
@@ -150,14 +150,14 @@
|
||||
"victory": true,
|
||||
"roundsPassed": 15,
|
||||
"eliminatedRound": null,
|
||||
"lp": 26,
|
||||
"lp": 27,
|
||||
"bandId": "band_ermengard",
|
||||
"title": {"id":"comment_1","name":"卫戍之星","picId":"comment_icon_1","text":"对敌方领袖造成伤害最高(仅胜利时)"},
|
||||
"trophies": 0,
|
||||
"reward": 400,
|
||||
"stats": {"activatedLayers":398,"bossDamage":1327500,"dmgDealt":3282365,"gold":144,"itemsEquipped":16,"kills":384,"leaks":1,"lpLost":1,"merges":4,"perfectRounds":12,"refreshes":18},
|
||||
"stats": {"activatedLayers":402,"bossDamage":1327500,"dmgDealt":3284809,"gold":144,"itemsEquipped":16,"kills":385,"leaks":0,"lpLost":0,"merges":4,"perfectRounds":13,"refreshes":18},
|
||||
"lineup": ["6_08_a@12,8","1_17_b@11,7","4_14_a@11,8[5_03_e_a]","6_18_a@10,4[3_02_e_a+3_05_e_a]","4_10_a@10,5[3_02_e_b+3_08_e_b]","6_02_a@10,6","1_19_b@10,8[4_05_e_a]","1_08_a@9,9[1_01_e_a+1_02_e_b]"],
|
||||
"bonds": ["arcaneShip 2/34","kazimierzShip 0/10","kjeragShip 0/2","miraShip 1/3","preciShip 2/73","sargonShip 0/8","siracusaShip 1/230","soloShip 1/3","steadShip 0/2","suntShip 1/0","swiftShip 1/55","yanShip 0/6"]
|
||||
"bonds": ["arcaneShip 2/34","kazimierzShip 0/10","kjeragShip 0/2","miraShip 1/3","preciShip 2/73","sargonShip 0/8","siracusaShip 1/234","soloShip 1/3","steadShip 0/2","suntShip 1/0","swiftShip 1/55","yanShip 0/6"]
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -246,7 +246,7 @@
|
||||
"combat": "client",
|
||||
"boost": null,
|
||||
"setup": {"stageId":"act1autochess_m03","bossId":"boss_5","hiddenBossId":"boss_8","factions":["TIMES","DOT","INVISIBLE"]},
|
||||
"end": {"victory":true,"roundsPassed":14,"hiddenReached":true,"hiddenCleared":false,"reason":"victory","teamLp":0,"bossPoolLeft":2633655,"virtualMs":113700},
|
||||
"end": {"victory":true,"roundsPassed":14,"hiddenReached":true,"hiddenCleared":false,"reason":"victory","teamLp":0,"bossPoolLeft":3039280,"virtualMs":113700},
|
||||
"rng": {"setup":25,"shop":254,"waves":0,"draft":42,"bots":8253,"meta":13},
|
||||
"errors": {"engine":0,"logged":0,"sim":0,"dispatcher":0},
|
||||
"rounds": [
|
||||
@@ -302,7 +302,7 @@
|
||||
"title": {"id":"comment_1","name":"卫戍之星","picId":"comment_icon_1","text":"对敌方领袖造成伤害最高(仅胜利时)"},
|
||||
"trophies": 0,
|
||||
"reward": 425,
|
||||
"stats": {"activatedLayers":473,"bossDamage":1746345,"dmgDealt":3598968,"gold":151,"itemsEquipped":18,"kills":422,"leaks":0,"lpLost":0,"merges":4,"perfectRounds":13,"refreshes":21},
|
||||
"stats": {"activatedLayers":473,"bossDamage":1340720,"dmgDealt":3211842,"gold":151,"itemsEquipped":18,"kills":420,"leaks":0,"lpLost":0,"merges":4,"perfectRounds":13,"refreshes":21},
|
||||
"lineup": ["4_14_b@12,8[5_01_e_a+2_01_e_b]","3_19_a@11,7[3_02_e_b]","4_20_b@11,8[3_11_e_b+3_06_e_a]","4_10_a@10,6","6_17_a@10,8[4_10_e_b+4_05_e_a]","1_08_a@9,5[1_01_e_a+1_02_e_a]","5_07_a@9,6","1_19_b@9,9[3_08_e_a+3_01_e_a]"],
|
||||
"bonds": ["arcaneShip 1/18","kazimierzShip 1/88","kjeragShip 0/2","miraShip 1/3","preciShip 1/72","raidShip 1/121","sargonShip 0/8","siracusaShip 1/117","soloShip 1/1","steadShip 0/12","suntShip 1/0","swiftShip 1/53"]
|
||||
}
|
||||
@@ -393,7 +393,7 @@
|
||||
"combat": "client",
|
||||
"boost": null,
|
||||
"setup": {"stageId":"act1autochess_m03","bossId":"boss_5","hiddenBossId":"boss_8","factions":["TIMES","DOT","INVISIBLE"]},
|
||||
"end": {"victory":false,"roundsPassed":13,"hiddenReached":false,"hiddenCleared":false,"reason":"defeat","teamLp":0,"bossPoolLeft":2424900,"virtualMs":107800},
|
||||
"end": {"victory":false,"roundsPassed":13,"hiddenReached":false,"hiddenCleared":false,"reason":"defeat","teamLp":0,"bossPoolLeft":2418932,"virtualMs":107800},
|
||||
"rng": {"setup":25,"shop":191,"waves":0,"draft":42,"bots":8021,"meta":6},
|
||||
"errors": {"engine":0,"logged":0,"sim":0,"dispatcher":0},
|
||||
"rounds": [
|
||||
@@ -431,11 +431,11 @@
|
||||
},
|
||||
{
|
||||
"round": 12,
|
||||
"ai_0": [1,12,13,0,0,6,8,"53598e5f",286,"arcaneShip 1/0, kazimierzShip 1/64, kjeragShip 0/2, preciShip 1/34, raidShip 1/97, sargonShip 0/8, siracusaShip 1/67, soloShip 1/1, steadShip 0/12, suntShip 1/0, swiftShip 1/23",22,31,9,111]
|
||||
"ai_0": [1,13,13,0,0,6,8,"53598e5f",286,"arcaneShip 1/0, kazimierzShip 1/64, kjeragShip 0/2, preciShip 1/34, raidShip 1/97, sargonShip 0/8, siracusaShip 1/67, soloShip 1/1, steadShip 0/12, suntShip 1/0, swiftShip 1/23",23,31,8,111]
|
||||
},
|
||||
{
|
||||
"round": 13,
|
||||
"ai_0": [1,12,12,0,0,6,8,"065b4c96",375,"arcaneShip 1/6, kazimierzShip 1/80, kjeragShip 0/2, miraShip 1/3, preciShip 1/52, raidShip 1/113, sargonShip 0/8, siracusaShip 1/87, soloShip 1/1, steadShip 0/12, suntShip 1/0, swiftShip 1/33",115,115,0,125]
|
||||
"ai_0": [1,13,12,0,0,6,8,"065b4c96",375,"arcaneShip 1/6, kazimierzShip 1/80, kjeragShip 0/2, miraShip 1/3, preciShip 1/52, raidShip 1/113, sargonShip 0/8, siracusaShip 1/87, soloShip 1/1, steadShip 0/12, suntShip 1/0, swiftShip 1/33",115,115,0,125]
|
||||
}
|
||||
],
|
||||
"players": {
|
||||
@@ -449,7 +449,7 @@
|
||||
"title": {"id":"comment_2","name":"不朽盟约","picId":"comment_icon_2","text":"激活的盟约层数总和最高"},
|
||||
"trophies": 0,
|
||||
"reward": 340,
|
||||
"stats": {"activatedLayers":412,"bossDamage":575100,"dmgDealt":3381027,"gold":137,"itemsEquipped":16,"kills":404,"leaks":15,"lpLost":15,"merges":4,"perfectRounds":10,"refreshes":13},
|
||||
"stats": {"activatedLayers":412,"bossDamage":581068,"dmgDealt":3404769,"gold":137,"itemsEquipped":16,"kills":405,"leaks":14,"lpLost":14,"merges":4,"perfectRounds":10,"refreshes":13},
|
||||
"lineup": ["4_14_b@12,5[2_01_e_a+5_01_e_a]","3_19_a@12,6[3_02_e_b]","4_20_b@11,8[3_11_e_b+3_06_e_a]","4_10_a@10,3","5_07_a@10,7","6_17_a@10,8[4_10_e_b]","1_08_a@9,5[1_01_e_a+1_02_e_a]","1_19_b@9,9[3_08_e_a+3_01_e_a]"],
|
||||
"bonds": ["arcaneShip 1/12","kazimierzShip 1/80","kjeragShip 0/2","miraShip 0/3","preciShip 1/62","raidShip 1/113","sargonShip 0/8","siracusaShip 1/101","soloShip 1/1","steadShip 0/12","suntShip 1/0","swiftShip 1/43"]
|
||||
}
|
||||
@@ -692,13 +692,13 @@
|
||||
},
|
||||
{
|
||||
"round": 12,
|
||||
"ai_0": [0,0,13,0,0,6,0,"811c9dc5",0,"deputShip 0/2, indomShip 0/8, kazimierzShip 0/2, kjeragShip 0/2, raidShip 0/3, siracusaShip 0/32, skillfulShip 0/12, soloShip 0/5, steadShip 0/15, suntShip 0/2, swiftShip 0/12",13,50,37,113],
|
||||
"ai_1": [1,2,15,0,2,6,8,"74bedaa1",129,"arcaneShip 2/30, kazimierzShip 0/2, preciShip 1/42, sargonShip 1/43, skillfulShip 1/14, suntShip 1/0, swiftShip 0/10",28,50,22,120]
|
||||
"ai_0": [0,0,13,0,0,6,0,"811c9dc5",0,"deputShip 0/2, indomShip 0/8, kazimierzShip 0/2, kjeragShip 0/2, raidShip 0/2, siracusaShip 0/32, skillfulShip 0/12, soloShip 0/5, steadShip 0/14, suntShip 0/2, swiftShip 0/12",16,50,34,113],
|
||||
"ai_1": [1,2,15,0,2,6,8,"1b0c894f",172,"arcaneShip 2/33, kazimierzShip 0/2, preciShip 1/62, sargonShip 1/63, skillfulShip 1/14, suntShip 1/0, swiftShip 0/10",39,50,11,120]
|
||||
},
|
||||
{
|
||||
"round": 13,
|
||||
"ai_0": [0,0,0,0,0,6,0,"811c9dc5",0,"deputShip 0/2, indomShip 0/8, kazimierzShip 0/2, kjeragShip 0/2, raidShip 0/3, siracusaShip 0/32, skillfulShip 0/12, soloShip 0/5, steadShip 0/15, suntShip 0/2, swiftShip 0/12",null,null,null,113],
|
||||
"ai_1": [0,0,14,0,0,6,0,"811c9dc5",0,"arcaneShip 0/40, kazimierzShip 0/2, preciShip 0/46, sargonShip 0/43, skillfulShip 0/14, swiftShip 0/10",38,49,11,136]
|
||||
"ai_0": [0,0,0,0,0,6,0,"811c9dc5",0,"deputShip 0/2, indomShip 0/8, kazimierzShip 0/2, kjeragShip 0/2, raidShip 0/2, siracusaShip 0/32, skillfulShip 0/12, soloShip 0/5, steadShip 0/14, suntShip 0/2, swiftShip 0/12",null,null,null,113],
|
||||
"ai_1": [0,0,14,0,0,6,0,"811c9dc5",0,"arcaneShip 0/46, kazimierzShip 0/2, preciShip 0/66, sargonShip 0/63, skillfulShip 0/14, swiftShip 0/10",41,49,8,136]
|
||||
}
|
||||
],
|
||||
"players": {
|
||||
@@ -712,9 +712,9 @@
|
||||
"title": {"id":"comment_5","name":"万事俱备","picId":"comment_icon_5","text":"装备配发数量最多"},
|
||||
"trophies": 2,
|
||||
"reward": 255,
|
||||
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":1366383,"gold":113,"itemsEquipped":10,"kills":152,"leaks":81,"lpLost":29,"merges":2,"perfectRounds":5,"refreshes":9},
|
||||
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":1409847,"gold":113,"itemsEquipped":10,"kills":155,"leaks":78,"lpLost":29,"merges":2,"perfectRounds":5,"refreshes":9},
|
||||
"lineup": [],
|
||||
"bonds": ["deputShip 0/2","indomShip 0/8","kazimierzShip 0/2","kjeragShip 0/2","raidShip 0/3","siracusaShip 0/32","skillfulShip 0/12","soloShip 0/5","steadShip 0/15","suntShip 0/2","swiftShip 0/12"]
|
||||
"bonds": ["deputShip 0/2","indomShip 0/8","kazimierzShip 0/2","kjeragShip 0/2","raidShip 0/2","siracusaShip 0/32","skillfulShip 0/12","soloShip 0/5","steadShip 0/14","suntShip 0/2","swiftShip 0/12"]
|
||||
},
|
||||
"ai_1": {
|
||||
"alive": false,
|
||||
@@ -726,9 +726,9 @@
|
||||
"title": {"id":"comment_4","name":"精英云集","picId":"comment_icon_4","text":"晋升精锐次数最多"},
|
||||
"trophies": 3,
|
||||
"reward": 298,
|
||||
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":3587885,"gold":136,"itemsEquipped":11,"kills":249,"leaks":51,"lpLost":34,"merges":4,"perfectRounds":8,"refreshes":22},
|
||||
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":3792350,"gold":136,"itemsEquipped":11,"kills":263,"leaks":37,"lpLost":32,"merges":4,"perfectRounds":8,"refreshes":22},
|
||||
"lineup": [],
|
||||
"bonds": ["arcaneShip 0/40","kazimierzShip 0/2","preciShip 0/46","sargonShip 0/43","skillfulShip 0/14","swiftShip 0/10"]
|
||||
"bonds": ["arcaneShip 0/46","kazimierzShip 0/2","preciShip 0/66","sargonShip 0/63","skillfulShip 0/14","swiftShip 0/10"]
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1090,7 +1090,7 @@
|
||||
"ai_0": [1,29,10,0,0,4,8,"3e2f54ac",46,"arcaneShip 1/16, indomShip 1/4, kazimierzShip 1/16, preciShip 0/8, soloShip 1/0, suntShip 1/0, swiftShip 1/10",8,21,13,52],
|
||||
"ai_1": [1,8,10,0,0,4,8,"c08bbdb7",47,"arcaneShip 1/4, kazimierzShip 1/13, kjeragShip 0/2, preciShip 1/12, sargonShip 0/4, soloShip 1/0, steadShip 2/10, swiftShip 1/8",7,21,14,52],
|
||||
"ai_2": [1,7,10,0,0,3,8,"2fd8f260",100,"deputShip 2/16, egirShip 0/2, kazimierzShip 0/4, kjeragShip 1/29, raidShip 0/16, skillfulShip 0/2, soloShip 0/4, steadShip 1/27, suntShip 1/4, swiftShip 0/2, victoriaShip 1/24, yanShip 0/10",10,21,11,51],
|
||||
"ai_3": [1,4,11,0,0,4,8,"849fa992",55,"arcaneShip 0/13, deputShip 1/8, kjeragShip 1/18, preciShip 1/13, sargonShip 0/2, skillfulShip 1/7, soloShip 1/9, steadShip 0/4",4,21,17,55]
|
||||
"ai_3": [1,4,11,0,0,4,8,"8d23d75f",55,"arcaneShip 0/13, deputShip 1/8, kjeragShip 1/18, preciShip 1/13, sargonShip 0/2, skillfulShip 1/7, soloShip 1/9, steadShip 0/4",6,21,15,55]
|
||||
},
|
||||
{
|
||||
"round": 8,
|
||||
@@ -1174,7 +1174,7 @@
|
||||
"title": {"id":"comment_6","name":"挥金如土","picId":"comment_icon_6","text":"消耗资金最多"},
|
||||
"trophies": 1,
|
||||
"reward": 149,
|
||||
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":878906,"gold":68,"itemsEquipped":10,"kills":48,"leaks":45,"lpLost":29,"merges":3,"perfectRounds":3,"refreshes":5},
|
||||
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":890981,"gold":68,"itemsEquipped":10,"kills":50,"leaks":43,"lpLost":29,"merges":3,"perfectRounds":3,"refreshes":5},
|
||||
"lineup": [],
|
||||
"bonds": ["arcaneShip 0/31","deputShip 0/10","kjeragShip 0/20","preciShip 0/17","sargonShip 0/2","skillfulShip 0/9","soloShip 0/11","steadShip 0/4","suntShip 0/2"]
|
||||
}
|
||||
@@ -1222,7 +1222,7 @@
|
||||
{
|
||||
"round": 6,
|
||||
"ai_0": [1,29,9,0,3,3,8,"41bbfcb2",32,"arcaneShip 0/2, deputShip 1/2, kjeragShip 0/2, preciShip 1/4, siracusaShip 1/12, soloShip 1/14, steadShip 0/2",25,25,0,39],
|
||||
"ai_1": [1,28,9,0,1,3,8,"5d508670",11,"arcaneShip 0/2, kjeragShip 0/9, preciShip 2/7, siracusaShip 1/0, soloShip 1/0, steadShip 1/4",22,22,0,37]
|
||||
"ai_1": [1,28,9,0,1,3,8,"ee24046e",11,"arcaneShip 0/2, kjeragShip 0/9, preciShip 2/7, siracusaShip 1/0, soloShip 1/0, steadShip 1/4",22,22,0,37]
|
||||
},
|
||||
{
|
||||
"round": 7,
|
||||
|
||||
+34
-45
@@ -1013,66 +1013,55 @@
|
||||
"time": 230,
|
||||
"ticks": 6900,
|
||||
"reason": "timeout",
|
||||
"killed": 79,
|
||||
"killed": 81,
|
||||
"total": 126,
|
||||
"unspawned": 0,
|
||||
"bossHpLeft": null,
|
||||
"rngDraws": 568,
|
||||
"rngDraws": 571,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {
|
||||
"p1": {
|
||||
"killed": 79,
|
||||
"total": 126,
|
||||
"perfect": false,
|
||||
"leaks": 47,
|
||||
"leaksUncounted": 0,
|
||||
"coins": 6,
|
||||
"dmg": 3625965,
|
||||
"bossDmg": 0,
|
||||
"heal": 73726,
|
||||
"deaths": 12,
|
||||
"layerGains": {"preciShip":2}
|
||||
}
|
||||
"p1": {"killed":81,"total":126,"perfect":false,"leaks":45,"leaksUncounted":0,"coins":6,"dmg":3939977,"bossDmg":0,"heal":90944,"deaths":6,"layerGains":{"preciShip":4}}
|
||||
},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_5_19_b",2,"uniequip_002_mlynar",3907,1,155,9,319089,12578,505,57,4],
|
||||
["p1",2,"op","chess_char_6_03_a",2,null,3649.5,1,153,1,63347,9646,3389,40,2],
|
||||
["p1",3,"op","chess_char_6_06_a",2,null,2223,1,141,9,376232,17794,732,73,2],
|
||||
["p1",4,"op","chess_char_5_17_b",1,"uniequip_002_f12yin",2738,1,74,6,134249,34756,12617,295,2],
|
||||
["p1",5,"op","chess_char_5_20_b",2,"uniequip_002_aglina",1382,1,10,0,114705,1182,705,42,5],
|
||||
["p1",6,"op","chess_char_5_21_b",1,"uniequip_002_sntlla",1629,1,84,0,216022,2324,401,113,3],
|
||||
["p1",7,"op","chess_char_5_22_b",1,"uniequip_002_nymph",1611,1,1,1,42732,1056,1056,11,4],
|
||||
["p1",8,"op","chess_char_5_23_b",1,"uniequip_002_reckpr",1610,1,3,0,0,2485,51822,72,4],
|
||||
["p1",9,"op","chess_char_6_01_a",2,null,1158,1,106,30,645243,1291,81,72,3],
|
||||
["p1",10,"op","chess_char_6_02_a",2,null,1687,1,7,20,1384858,7686,498,74,3],
|
||||
["p1",11,"op","chess_char_6_04_a",2,null,1161.9,1,130,1,64654,8281,903,0,3],
|
||||
["p1",12,"op","chess_char_6_05_a",2,null,1215,1,59,2,264834,2542,1017,68,5],
|
||||
["p1",1,"op","chess_char_5_19_b",2,"uniequip_002_mlynar",699.59,1,112,13,452146,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],
|
||||
["p1",5,"op","chess_char_5_20_b",2,"uniequip_002_aglina",1382,1,10,0,111106,1182,705,40,5],
|
||||
["p1",6,"op","chess_char_5_21_b",1,"uniequip_002_sntlla",1629,1,83,0,211134,2324,401,112,3],
|
||||
["p1",7,"op","chess_char_5_22_b",1,"uniequip_002_nymph",1611,1,1,1,24955,1242,844,10,4],
|
||||
["p1",8,"op","chess_char_5_23_b",1,"uniequip_002_reckpr",1610,1,3,0,0,2192,61470,82,4],
|
||||
["p1",9,"op","chess_char_6_01_a",2,null,1158,1,92,22,825066,1317,106,81,4],
|
||||
["p1",10,"op","chess_char_6_02_a",2,null,1687,1,7,28,1280417,1242,278,74,3],
|
||||
["p1",11,"op","chess_char_6_04_a",2,null,1202,1,9,2,80419,7606,2044,0,4],
|
||||
["p1",12,"op","chess_char_6_05_a",2,null,1215,1,59,2,282958,2542,1017,68,5],
|
||||
["p1",13,"token","token_10017_skadi2_dedant",null,null,100,0,13,0,0,0,0,0,null],
|
||||
["p1","~1","token","token_10017_skadi2_dedant",null,null,100,0,60,0,0,0,0,0,null],
|
||||
["p1","~2","token","token_10017_skadi2_dedant",null,null,100,0,131,0,0,0,0,0,null],
|
||||
["p1","~3","token","token_10017_skadi2_dedant",null,null,100,0,154,0,0,0,0,0,null]
|
||||
["p1","~2","token","token_10017_skadi2_dedant",null,null,100,0,101,0,0,0,0,0,null],
|
||||
["p1","~3","token","token_10017_skadi2_dedant",null,null,100,0,142,0,0,0,0,0,null],
|
||||
["p1","~4","token","token_10017_skadi2_dedant",null,null,100,1,150,0,0,0,0,0,null]
|
||||
],
|
||||
"enemies": {
|
||||
"enemy_10045_parrot": [1,0,1,0,44064],
|
||||
"enemy_10098_crhro": [1,0,1,4685,94997],
|
||||
"enemy_10124_uashld_2": [12,0,10,34007,659017],
|
||||
"enemy_1019_jshoot_2": [1,1,0,1861,16718],
|
||||
"enemy_1043_zomsbr": [72,54,18,618,974327],
|
||||
"enemy_1061_zomshd": [30,18,12,24836,1664045],
|
||||
"enemy_1072_dlancer": [1,1,0,2738,37150],
|
||||
"enemy_1165_duhond": [1,1,0,0,17337],
|
||||
"enemy_10098_crhro": [1,1,0,9194,185752],
|
||||
"enemy_10124_uashld_2": [12,2,6,48061,1052907],
|
||||
"enemy_1019_jshoot_2": [1,1,0,1498,16718],
|
||||
"enemy_1043_zomsbr": [72,52,20,114,986155],
|
||||
"enemy_1061_zomshd": [30,20,10,24481,1553823],
|
||||
"enemy_1072_dlancer": [1,1,0,508,37150],
|
||||
"enemy_1165_duhond": [1,1,0,127,17337],
|
||||
"enemy_1196_msfyin_2": [1,1,0,0,3],
|
||||
"enemy_1209_sfden_2": [1,0,1,0,40185],
|
||||
"enemy_1273_stmgun_2": [1,1,0,30037,111451],
|
||||
"enemy_1209_sfden_2": [1,0,1,896,53527],
|
||||
"enemy_1273_stmgun_2": [1,0,1,18044,12298],
|
||||
"enemy_1355_mrfly": [1,1,0,0,37150],
|
||||
"enemy_1433_dsbasi_2": [1,1,0,134,35293],
|
||||
"enemy_2001_duckmi_2": [1,0,1,0,9483],
|
||||
"enemy_9006_actoxi": [1,0,1,0,2384]
|
||||
"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,154,6900,951,1017,7281,7430,78804,91,140,40,36,17,35845,1032,57,126,45,1,102,1,7,6],
|
||||
"events": {"atk":2283,"bounty":3,"deploy":28,"die":95,"dmg":7385,"engage":10,"fx":552,"heal":121,"layer":1,"leak":45,"skill":76,"spawn":142,"status":2410},
|
||||
"fx": {"aoe":8,"bombard":17,"bombardShell":17,"burst":7,"crit":50,"dodge":6,"explode":40,"firewall":2,"garrison":1,"iceSpike":90,"lightning":148,"lock":17,"lure":3,"revive":1,"snow":82,"soul":1,"sp":1,"storm":5,"talent":2,"telegraph":8,"tide":3,"wanted":38,"weightless":5},
|
||||
"snaps": "76864815 62849bad 979bf882 25b6b06a 5180c227 3ecd4ada 973ab3dc 34c4af0f c0357d8d 21dd059d b2e1cc4c 8a773c5e 69aa5545 f41c0b6e 34d38c11 fd5b4e85 3a8cd96d 541d94f7 b7150f71 e0eeba75 f3b17a4b 864eec43 64dedb33"
|
||||
"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},
|
||||
"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"
|
||||
},
|
||||
"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",
|
||||
|
||||
+85
-97
@@ -186,62 +186,62 @@
|
||||
"round": 12,
|
||||
"seed": 428893583,
|
||||
"waveId": "act1autochess_h05",
|
||||
"time": 196.37,
|
||||
"ticks": 5891,
|
||||
"time": 201.73,
|
||||
"ticks": 6052,
|
||||
"reason": "cleared",
|
||||
"killed": 127,
|
||||
"killed": 146,
|
||||
"total": 158,
|
||||
"unspawned": 0,
|
||||
"bossHpLeft": null,
|
||||
"rngDraws": 656,
|
||||
"rngDraws": 614,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {
|
||||
"p1": {
|
||||
"killed": 127,
|
||||
"killed": 146,
|
||||
"total": 158,
|
||||
"perfect": false,
|
||||
"leaks": 31,
|
||||
"leaks": 12,
|
||||
"leaksUncounted": 0,
|
||||
"coins": 8,
|
||||
"dmg": 1279084,
|
||||
"dmg": 1417534,
|
||||
"bossDmg": 0,
|
||||
"heal": 23617,
|
||||
"deaths": 13,
|
||||
"heal": 25396,
|
||||
"deaths": 8,
|
||||
"layerGains": {"sargonShip":5}
|
||||
}
|
||||
},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_6_03_a",2,null,0,0,173,0,379,7812,0,3,0],
|
||||
["p1",2,"op","chess_char_6_02_a",2,null,0,0,175,2,4099,4587,0,9,1],
|
||||
["p1",3,"op","chess_char_6_07_a",0,null,0,0,169,9,146057,3730,0,77,1],
|
||||
["p1",4,"op","chess_char_6_10_a",0,null,1865,1,182,0,26824,3730,0,28,1],
|
||||
["p1",5,"op","chess_char_6_11_a",2,null,1529,1,179,11,105846,7699,0,33,4],
|
||||
["p1",6,"op","chess_char_6_06_a",2,null,2080.4,1,157,13,102010,19207,0,105,3],
|
||||
["p1",7,"op","chess_char_5_22_a",2,null,1272,1,3,2,36737,0,0,27,2],
|
||||
["p1",8,"op","chess_char_6_01_a",2,null,1272,1,4,41,375365,0,0,160,3],
|
||||
["p1",9,"op","chess_char_6_04_a",2,null,1160,1,13,5,66082,0,0,118,2],
|
||||
["p1",10,"op","chess_char_6_05_a",2,null,1272,1,14,16,199814,2964,0,123,2],
|
||||
["p1",11,"op","chess_char_6_08_a",2,null,1372,1,5,28,215871,0,0,59,2],
|
||||
["p1",12,"op","chess_char_6_09_a",2,null,1224,1,11,0,0,0,23617,34,2],
|
||||
["p1",1,"op","chess_char_6_03_a",2,null,0,0,169,0,2034,5814,0,24,1],
|
||||
["p1",2,"op","chess_char_6_02_a",2,null,1026.4,1,171,6,34754,2032,0,3,6],
|
||||
["p1",3,"op","chess_char_6_07_a",0,null,1865,1,178,7,177671,1865,0,104,2],
|
||||
["p1",4,"op","chess_char_6_10_a",0,null,1865,1,177,5,99606,1865,0,99,2],
|
||||
["p1",5,"op","chess_char_6_11_a",2,null,0,0,167,25,173830,8783,0,48,7],
|
||||
["p1",6,"op","chess_char_6_06_a",2,null,2638,1,158,15,108249,19250,0,107,4],
|
||||
["p1",7,"op","chess_char_5_22_a",2,null,1272,1,3,2,27182,0,0,23,2],
|
||||
["p1",8,"op","chess_char_6_01_a",2,null,1272,1,4,38,276396,0,0,159,2],
|
||||
["p1",9,"op","chess_char_6_04_a",2,null,1160,1,13,8,63813,0,0,118,2],
|
||||
["p1",10,"op","chess_char_6_05_a",2,null,1272,1,14,18,244695,2453,0,128,2],
|
||||
["p1",11,"op","chess_char_6_08_a",2,null,1372,1,5,21,209303,0,0,53,3],
|
||||
["p1",12,"op","chess_char_6_09_a",2,null,1224,1,11,0,0,0,25396,42,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_10098_crhro": [1,1,0,1577,41472],
|
||||
"enemy_10099_crvln": [1,1,0,2964,20736],
|
||||
"enemy_1009_lurker": [1,1,0,16,3041],
|
||||
"enemy_10099_crvln": [1,1,0,2453,20736],
|
||||
"enemy_1009_lurker": [1,1,0,23,3041],
|
||||
"enemy_1010_demon": [1,1,0,0,10368],
|
||||
"enemy_1010_demon_2": [28,20,8,11373,543506],
|
||||
"enemy_1010_demon_2": [28,24,4,9519,566154],
|
||||
"enemy_10112_ymgds": [1,1,0,0,6912],
|
||||
"enemy_10116_ymgtop": [1,1,0,3450,13824],
|
||||
"enemy_10118_ymgprc": [1,0,1,5235,10561],
|
||||
"enemy_1071_dftman": [63,60,3,290,241610],
|
||||
"enemy_1072_dlancer": [60,41,19,24824,407969]
|
||||
"enemy_10116_ymgtop": [1,1,0,2924,13824],
|
||||
"enemy_10118_ymgprc": [1,0,1,8633,47535],
|
||||
"enemy_1071_dftman": [63,63,0,666,243855],
|
||||
"enemy_1072_dlancer": [60,53,7,16266,482782]
|
||||
},
|
||||
"hooks": [1,182,5891,853,853,1865,1862,60,140,171,23,22,0,28489,4121,43,158,31,1,141,2,0,12],
|
||||
"events": {"atk":998,"bounty":4,"deploy":22,"die":140,"dmg":1862,"engage":11,"fx":77,"heal":44,"layer":2,"leak":31,"skill":45,"spawn":172,"status":464},
|
||||
"fx": {"aoe":4,"dodge":15,"dp":18,"garrison":2,"revive":1,"slash":24,"sp":8,"spGain":3,"telegraph":2},
|
||||
"snaps": "1184691a ac872d2c 04c21bcf 302d411f 5ea6c6b7 1d6c2c6a d1adbc33 d86e6315 835cf160 a3576945 32ffef8a f9d81c1e 035b4b09 12f6f260 41a84026 a6a6ba61 9dd38c5e dcbccdf8 93092800 8b97b584"
|
||||
"hooks": [1,178,6052,992,992,2073,2070,71,154,166,35,33,0,37600,3935,56,158,12,1,155,2,0,11],
|
||||
"events": {"atk":1138,"bounty":4,"deploy":18,"die":154,"dmg":2070,"engage":11,"fx":174,"heal":53,"layer":2,"leak":12,"skill":68,"spawn":172,"status":449},
|
||||
"fx": {"aoe":8,"dodge":14,"dp":44,"garrison":2,"revive":1,"slash":86,"sp":14,"spGain":3,"telegraph":2},
|
||||
"snaps": "484fd662 4f4e076d 081948b0 d7bf1df0 c0aa2905 1b27e150 ab6cac50 1cbbd19b 1109a00b b8a562d0 58ac9b92 3126d9be 7b2d0323 7a11d03f b313b514 a71c9972 09816903 02ed5449 40a13ed4 00252786 174d9027"
|
||||
},
|
||||
"standin-05": {
|
||||
"about": "normal band 6 as stand-ins: chess_char_6_17_a→char_608_acpion chess_char_6_13_a→char_615_acspec chess_char_6_19_a→char_615_acspec chess_char_6_12_a→char_612_accast chess_char_6_15_a→char_614_acsupo chess_char_6_18_a→char_612_accast chess_char_6_20_a→char_613_acmedc",
|
||||
@@ -306,58 +306,46 @@
|
||||
"time": 183.7,
|
||||
"ticks": 5511,
|
||||
"reason": "cleared",
|
||||
"killed": 50,
|
||||
"killed": 25,
|
||||
"total": 98,
|
||||
"unspawned": 0,
|
||||
"bossHpLeft": null,
|
||||
"rngDraws": 345,
|
||||
"rngDraws": 272,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {
|
||||
"p1": {
|
||||
"killed": 50,
|
||||
"total": 98,
|
||||
"perfect": false,
|
||||
"leaks": 48,
|
||||
"leaksUncounted": 0,
|
||||
"coins": 8,
|
||||
"dmg": 676478,
|
||||
"bossDmg": 0,
|
||||
"heal": 30426,
|
||||
"deaths": 31,
|
||||
"layerGains": {"raidShip":26,"visiShip":12}
|
||||
}
|
||||
"p1": {"killed":25,"total":98,"perfect":false,"leaks":73,"leaksUncounted":0,"coins":4,"dmg":397046,"bossDmg":0,"heal":12225,"deaths":31,"layerGains":{"raidShip":24}}
|
||||
},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_3_12_b",2,"none",1904,1,140,10,155395,5504,915,21,3],
|
||||
["p1",2,"op","chess_char_4_09_b",0,"none",0,0,6,10,119787,3510,0,39,1],
|
||||
["p1",3,"op","chess_char_3_05_b",2,"none",0,0,90,2,23950,8566,0,18,2],
|
||||
["p1",4,"op","chess_char_3_18_b",2,"none",0,0,93,3,28745,9190,2808,27,2],
|
||||
["p1",5,"op","chess_char_4_04_b",1,"none",0,0,137,0,25476,10224,0,40,9],
|
||||
["p1",6,"op","chess_char_4_07_b",1,"none",0,0,101,3,28031,10981,0,27,1],
|
||||
["p1",7,"op","chess_char_4_16_b",1,"none",0,0,139,7,42175,16104,0,70,12],
|
||||
["p1",8,"op","chess_char_3_01_b",2,"none",0,0,122,1,16716,3020,0,24,1],
|
||||
["p1",9,"op","chess_char_3_04_b",2,"none",0,0,4,0,0,15932,26703,25,2],
|
||||
["p1",10,"op","chess_char_3_21_b",2,"none",0,0,118,12,175716,7911,0,55,1],
|
||||
["p1",11,"op","chess_char_4_02_b",1,"none",0,0,124,2,41362,2966,0,27,1],
|
||||
["p1",12,"op","chess_char_4_13_b",1,"none",0,0,103,0,19124,2704,0,26,2]
|
||||
["p1",1,"op","chess_char_3_12_b",2,"none",1904,1,138,4,33527,4810,222,6,1],
|
||||
["p1",2,"op","chess_char_4_09_b",0,"none",0,0,6,2,12272,3510,0,5,1],
|
||||
["p1",3,"op","chess_char_3_05_b",2,"none",0,0,90,1,29963,11344,0,19,2],
|
||||
["p1",4,"op","chess_char_3_18_b",2,"none",0,0,12,1,32236,5744,2553,22,1],
|
||||
["p1",5,"op","chess_char_4_04_b",1,"none",0,0,137,0,21284,11506,0,43,9],
|
||||
["p1",6,"op","chess_char_4_07_b",1,"none",0,0,93,0,13096,7538,0,19,1],
|
||||
["p1",7,"op","chess_char_4_16_b",1,"none",0,0,135,2,26045,13645,0,38,12],
|
||||
["p1",8,"op","chess_char_3_01_b",2,"none",0,0,128,1,13435,3020,0,21,1],
|
||||
["p1",9,"op","chess_char_3_04_b",2,"none",0,0,4,0,0,1374,9451,11,1],
|
||||
["p1",10,"op","chess_char_3_21_b",2,"none",0,0,112,11,185272,6695,0,50,1],
|
||||
["p1",11,"op","chess_char_4_02_b",1,"none",0,0,2,0,16202,1483,0,17,1],
|
||||
["p1",12,"op","chess_char_4_13_b",1,"none",0,0,101,3,13715,3085,0,23,1]
|
||||
],
|
||||
"enemies": {
|
||||
"enemy_10162_mnctpt": [1,1,0,7378,39813],
|
||||
"enemy_1019_jshoot": [1,1,0,295,4479],
|
||||
"enemy_1019_jshoot_2": [1,1,0,837,6718],
|
||||
"enemy_1021_bslime": [1,1,0,1648,6121],
|
||||
"enemy_1023_jmage": [1,1,0,2497,5474],
|
||||
"enemy_10162_mnctpt": [1,0,1,13739,31746],
|
||||
"enemy_1019_jshoot": [1,1,0,769,4479],
|
||||
"enemy_1019_jshoot_2": [1,1,0,1779,6718],
|
||||
"enemy_1021_bslime": [1,1,0,2095,6121],
|
||||
"enemy_1023_jmage": [1,0,1,3326,1518],
|
||||
"enemy_1025_reveng": [1,1,0,0,12442],
|
||||
"enemy_1026_aghost": [1,1,0,0,9456],
|
||||
"enemy_1043_zomsbr": [1,1,0,0,6285],
|
||||
"enemy_1251_lysyta_2": [57,33,24,13447,289829],
|
||||
"enemy_1252_lysytb_2": [21,8,13,29953,226804],
|
||||
"enemy_1329_cbshld_2": [12,1,11,40556,69057]
|
||||
"enemy_1043_zomsbr": [1,0,1,0,0],
|
||||
"enemy_1251_lysyta_2": [57,15,42,6671,148451],
|
||||
"enemy_1252_lysytb_2": [21,4,17,25366,127156],
|
||||
"enemy_1329_cbshld_2": [12,1,11,20011,48959]
|
||||
},
|
||||
"hooks": [1,140,5511,596,596,875,906,94,81,139,37,37,0,7322,36,60,98,48,1,89,7,0,4],
|
||||
"events": {"atk":684,"bounty":4,"deploy":42,"die":91,"dmg":906,"engage":11,"fx":62,"heal":67,"layer":7,"leak":48,"skill":74,"spawn":110,"status":117},
|
||||
"fx": {"blink":10,"camouflage":1,"dodge":6,"dp":13,"explode":1,"garrison":7,"slash":24},
|
||||
"snaps": "be6d1821 fa43a30d 52099f77 a860ccb6 ea311a6e 44affa90 9dabf4d8 83adbc77 77dfae35 f02fd736 470fba6a a9871a60 b7e054aa ae8c4b73 55df9303 1c374baa 0d780d78 e03a2b60 b7879d42"
|
||||
"hooks": [1,138,5511,428,428,618,635,38,56,137,32,32,0,5767,24,40,98,73,1,59,3,0,6],
|
||||
"events": {"atk":493,"bounty":2,"deploy":40,"die":64,"dmg":635,"engage":11,"fx":32,"heal":36,"layer":3,"leak":73,"skill":64,"spawn":110,"status":83},
|
||||
"fx": {"blink":8,"camouflage":1,"dodge":6,"dp":5,"explode":1,"garrison":3,"slash":8},
|
||||
"snaps": "be6d1821 69cb5865 7bea5cb3 02fefb75 5eacb174 5bc1814c a70bea6d 0de1251c 172a35f2 f9001627 db7b6b38 a6083013 e2198a24 0adb9d99 8eed5e8b b756dcfe 538dc28e 876d2f95 835a73d1"
|
||||
},
|
||||
"standin-07": {
|
||||
"about": "elite band 6 as stand-ins: chess_char_4_17_b→char_610_acfend chess_char_4_18_b→char_602_cdfend chess_char_5_05_b→char_602_cdfend chess_char_4_19_b→char_608_acpion chess_char_5_01_b→char_600_cpione chess_char_4_22_b→char_609_acguad chess_char_4_23_b→char_609_acguad chess_char_5_06_b→char_609_acguad chess_char_4_20_b→char_603_csnipe chess_char_4_24_b→char_604_ccast chess_char_5_02_b→char_604_ccast chess_char_5_03_b→char_612_accast",
|
||||
@@ -438,47 +426,47 @@
|
||||
"time": 230,
|
||||
"ticks": 6900,
|
||||
"reason": "timeout",
|
||||
"killed": 36,
|
||||
"killed": 35,
|
||||
"total": 179,
|
||||
"unspawned": 0,
|
||||
"bossHpLeft": null,
|
||||
"rngDraws": 1087,
|
||||
"rngDraws": 1045,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {"p1":{"killed":36,"total":179,"perfect":false,"leaks":143,"leaksUncounted":0,"coins":2,"dmg":1859123,"bossDmg":0,"heal":138461,"deaths":10,"layerGains":{}}},
|
||||
"players": {"p1":{"killed":35,"total":179,"perfect":false,"leaks":144,"leaksUncounted":0,"coins":2,"dmg":1736036,"bossDmg":0,"heal":110120,"deaths":11,"layerGains":{}}},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_5_08_b",2,"uniequip_002_acfend",3167.17,1,165,4,83889,36030,0,116,3],
|
||||
["p1",2,"op","chess_char_5_14_b",2,"uniequip_002_acpion",1904,1,194,7,473061,9225,0,48,8],
|
||||
["p1",3,"op","chess_char_5_19_b",0,"uniequip_002_sharp2",0,0,156,7,350021,33747,0,99,3],
|
||||
["p1",4,"op","chess_char_5_07_b",2,"none",3334,1,203,1,30240,30649,0,29,2],
|
||||
["p1",5,"op","chess_char_5_13_b",2,"uniequip_002_acguad",2176.17,1,129,7,177239,32096,0,89,4],
|
||||
["p1",6,"op","chess_char_5_17_b",2,"uniequip_002_acspec",1448,1,188,5,87979,26616,0,142,0],
|
||||
["p1",7,"op","chess_char_5_10_b",2,"none",1131,1,4,0,74712,0,0,155,4],
|
||||
["p1",8,"op","chess_char_5_11_b",2,"uniequip_002_acmedc",2262.4,1,5,0,0,0,138461,78,3],
|
||||
["p1",9,"op","chess_char_5_12_b",2,"uniequip_002_acsupo",1430,1,11,2,99017,0,0,136,3],
|
||||
["p1",10,"op","chess_char_5_15_b",2,"none",1510,1,13,0,76181,0,0,234,4],
|
||||
["p1",11,"op","chess_char_5_18_b",2,"uniequip_002_acnipe",2380.5,1,6,3,299976,0,0,164,3],
|
||||
["p1",12,"op","chess_char_5_20_b",2,"uniequip_002_acsupo",1430,1,14,0,106807,0,0,136,3],
|
||||
["p1",1,"op","chess_char_5_08_b",2,"uniequip_002_acfend",2051.95,1,164,4,77661,36640,0,117,3],
|
||||
["p1",2,"op","chess_char_5_14_b",2,"uniequip_002_acpion",1904,1,194,9,521070,9584,0,48,8],
|
||||
["p1",3,"op","chess_char_5_19_b",0,"uniequip_002_sharp2",4154.5,1,204,5,256988,30222,0,77,3],
|
||||
["p1",4,"op","chess_char_5_07_b",2,"none",2619.79,1,203,2,42832,27659,0,38,3],
|
||||
["p1",5,"op","chess_char_5_13_b",2,"uniequip_002_acguad",3411,1,205,4,86863,13306,0,44,2],
|
||||
["p1",6,"op","chess_char_5_17_b",2,"uniequip_002_acspec",1448,1,189,4,87684,26616,0,145,0],
|
||||
["p1",7,"op","chess_char_5_10_b",2,"none",1131,1,4,0,76667,0,0,155,4],
|
||||
["p1",8,"op","chess_char_5_11_b",2,"uniequip_002_acmedc",2262.4,1,5,0,0,0,110120,78,3],
|
||||
["p1",9,"op","chess_char_5_12_b",2,"uniequip_002_acsupo",1430,1,11,2,101246,0,0,136,3],
|
||||
["p1",10,"op","chess_char_5_15_b",2,"none",1510,1,13,0,87081,0,0,232,4],
|
||||
["p1",11,"op","chess_char_5_18_b",2,"uniequip_002_acnipe",2380.5,1,6,5,303540,0,0,167,3],
|
||||
["p1",12,"op","chess_char_5_20_b",2,"uniequip_002_acsupo",1430,1,14,0,94405,0,0,125,3],
|
||||
["-","~1","device","trap_1105_accrate",null,null,100,1,1,0,0,0,0,0,null],
|
||||
["-","~2","device","trap_1105_accrate",null,null,100,1,2,0,0,0,0,0,null],
|
||||
["-","~3","device","trap_1105_accrate",null,null,100,1,3,0,0,0,0,0,null]
|
||||
],
|
||||
"enemies": {
|
||||
"enemy_1072_dlancer": [1,1,0,3008,37150],
|
||||
"enemy_1081_sotisd": [1,0,1,0,27095],
|
||||
"enemy_1092_mdgint": [1,0,1,0,33],
|
||||
"enemy_1072_dlancer": [1,1,0,1609,37150],
|
||||
"enemy_1081_sotisd": [1,0,1,194,28396],
|
||||
"enemy_1092_mdgint": [1,0,1,0,505],
|
||||
"enemy_1116_liprr": [1,0,1,0,6095],
|
||||
"enemy_1116_liprr_2": [1,0,1,0,2364],
|
||||
"enemy_1118_lidbox_2": [1,0,1,0,1344],
|
||||
"enemy_1119_vofsd": [1,0,1,0,889],
|
||||
"enemy_1121_lifbos": [1,0,1,0,1997],
|
||||
"enemy_1249_lysdb_2": [60,16,44,44297,925272],
|
||||
"enemy_1251_lysyta": [63,18,45,8302,477784],
|
||||
"enemy_1254_lypa_2": [48,1,46,112756,379100]
|
||||
"enemy_1249_lysdb_2": [60,14,46,46440,808178],
|
||||
"enemy_1251_lysyta": [63,18,45,8182,493665],
|
||||
"enemy_1254_lypa_2": [48,2,45,87602,355453]
|
||||
},
|
||||
"hooks": [1,203,6900,1914,1914,3154,3238,154,46,188,40,41,0,27753,17018,59,179,142,1,51,0,0,24],
|
||||
"events": {"atk":2198,"bounty":1,"deploy":21,"die":46,"dmg":3227,"engage":11,"fx":296,"heal":145,"leak":142,"skill":85,"spawn":194,"status":1301},
|
||||
"fx": {"aoe":89,"displace":4,"dodge":50,"dp":15,"shieldBreak":60,"slash":64,"sp":4,"spGain":10},
|
||||
"snaps": "c4ba1bfb 2dfd8eae 9edfcbdb 398871eb 8ec5c018 bdeb7f73 3a80c711 b3542ba8 7c2bcdeb 332b7d77 cfba3c82 e42b9504 e04cec26 299bbeab 55c539ae fb163352 d1b5dcef e0628f10 16c64f3c f935f6ce dfa3bfea 0a6ae300 8f573ae7"
|
||||
"hooks": [1,205,6900,1792,1792,3023,3084,153,46,189,39,41,0,26837,16854,58,179,143,1,46,0,0,6],
|
||||
"events": {"atk":2045,"bounty":1,"deploy":23,"die":46,"dmg":3073,"engage":11,"fx":280,"heal":140,"leak":143,"skill":84,"spawn":194,"status":1275},
|
||||
"fx": {"aoe":90,"displace":4,"dodge":34,"dp":17,"shieldBreak":59,"slash":64,"sp":2,"spGain":10},
|
||||
"snaps": "c4ba1bfb fae78ec3 d95288ac 1e7366a4 dbbd0efb 2511f256 d2703cda dc932034 2d5006eb 8fcfa286 0f2d3b1e af1f7c99 b655c535 e4d7c5af 88362233 8adc2140 c0aab784 c923256c 5e8e81a4 b5c29988 bf00ddb2 6593e2b4 58d326a5"
|
||||
},
|
||||
"standin-09": {
|
||||
"about": "elite band 7 as stand-ins: chess_char_6_03_b→char_610_acfend chess_char_6_02_b→char_608_acpion chess_char_6_07_b→char_617_sharp2 chess_char_6_10_b→char_617_sharp2 chess_char_6_11_b→char_608_acpion chess_char_6_06_b→char_609_acguad chess_char_5_22_b→char_611_acnipe chess_char_6_01_b→char_611_acnipe chess_char_6_04_b→char_614_acsupo chess_char_6_05_b→char_611_acnipe chess_char_6_08_b→char_612_accast chess_char_6_09_b→char_613_acmedc",
|
||||
|
||||
@@ -111,18 +111,21 @@ test('战术家 援军 (伺夜): the tactical point is the tile in FRONT along t
|
||||
});
|
||||
|
||||
test('突袭 (raidShip): the landing tile beside the enemy turns with the member direction (equal candidates)', () => {
|
||||
// a diagonal-only range: two equally near landing tiles cover the enemy — the tie resolves in the member's frame
|
||||
// a diagonal-only range: two equally near landing tiles cover the enemy — the tie resolves in the member's frame. The
|
||||
// enemy stands inside the player's own board (rows 9–12, cols 2–10): a member lands only there since 0.2.0
|
||||
// (Battle.onOwnBoard, DESIGN §25.18), so all four diagonal tiles around (10, 6) are candidates in every direction
|
||||
const ER = 10, EC = 6;
|
||||
const rec = chessRec({ id: 'r_diag', bonds: ['raidShip'], profession: 'WARRIOR', skill: null, rangeGrid: [[1, 1], [-1, 1]] });
|
||||
const land = (dir) => {
|
||||
const h = makeBattle({
|
||||
stage: OPEN, rect: RECT, routes: FAR_ROUTE, defs: { chess: { r_diag: rec }, enemies: { e_d: enemyRec({ key: 'e_d', hp: 1e6, speed: 0 }) } },
|
||||
bonds: { raidShip: { count: 1, active: true, tier: 1, layers: 0 } },
|
||||
units: [{ chessId: 'r_diag', row: 15, col: 3, dir, abs: true }],
|
||||
enemies: [{ key: 'e_d', pos: [R0, C0], route: walkRoute([R0, C0]) }], autoFinish: false, timeLimit: 60,
|
||||
enemies: [{ key: 'e_d', pos: [ER, EC], route: walkRoute([ER, EC]) }], autoFinish: false, timeLimit: 60,
|
||||
});
|
||||
const u = h.unit('r_diag');
|
||||
assert.ok(h.runUntil(() => u.alive && u.deployed && Math.max(Math.abs(u.tileR - R0), Math.abs(u.tileC - C0)) <= 2, 30), `${dir}: jumped next to the enemy`);
|
||||
return toLocal(u.tileR - R0, u.tileC - C0, dir);
|
||||
assert.ok(h.runUntil(() => u.alive && u.deployed && Math.max(Math.abs(u.tileR - ER), Math.abs(u.tileC - EC)) <= 2, 30), `${dir}: jumped next to the enemy`);
|
||||
return toLocal(u.tileR - ER, u.tileC - EC, dir);
|
||||
};
|
||||
const right = land('RIGHT');
|
||||
assert.deepEqual(right, [-1, -1], 'RIGHT: the lower of the two diagonal tiles behind the enemy (tile-key order, as before)');
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
// test/sim/feedback5-catapult-smog.test.js — 自制投石机's 「索敌不受阻挡影响」 (community report of 2026-10-06, item 24, a
|
||||
// player's report of the official game: 「投石车」敌人如果被蒸汽地板上的干员阻挡会不进行攻击; DESIGN §25.18).
|
||||
// PRTS 自制投石机 天赋: 「普通攻击为3连击…索敌不受阻挡影响,且不会因丢失目标而结束攻击」. An operator on the 排气格栅 smog
|
||||
// (战场#07 下半, tile_smog) is 隐匿 for enemy ranged attacks; any other enemy still attacks the operator that blocks it
|
||||
// ("阻挡优先级最高"), but the catapult's targeting ignores its block, so that blocker is no target: alone, it is not attacked.
|
||||
// Run: node --test test/sim/feedback5-catapult-smog.test.js
|
||||
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { makeBattle, chessRec, enemyRec, flatStage, checkInvariants } from '../helpers/battleHarness.js';
|
||||
|
||||
const KEY = 'enemy_10162_mnctpt'; // 自制投石机 (RANGED, range 4.0)
|
||||
const wall = chessRec({ id: 't_wall', profession: 'TANK', stats: { atk: 0, maxHp: 1e9, def: 0, blockCnt: 3 }, rangeGrid: [[0, 0]], skill: null });
|
||||
const other = chessRec({ id: 't_other', profession: 'SNIPER', stats: { atk: 0, maxHp: 1e9, def: 0, blockCnt: 0 }, rangeGrid: [[0, 0]], skill: null });
|
||||
const kits = { t_wall: () => ({ trait: { noAttack: true } }), t_other: () => ({ trait: { noAttack: true } }) };
|
||||
const route = { motion: 'WALK', start: [9, 10], end: [9, 2], checkpoints: [] };
|
||||
const shooter = enemyRec({ key: 'enemy_t_shooter', hp: 1e9, atk: 100, range: 3, speed: 1, bat: 2 }); // an ordinary ranged walker
|
||||
|
||||
function run({ smog, withOther = false, key = KEY }) {
|
||||
const stage = flatStage();
|
||||
if (smog) stage.rows[9] = stage.rows[9].slice(0, 6) + 'g' + stage.rows[9].slice(7); // the blocker's tile (9,6)
|
||||
const units = [{ chessId: 't_wall', row: 9, col: 6 }];
|
||||
if (withOther) units.push({ chessId: 't_other', row: 11, col: 6 });
|
||||
const h = makeBattle({ stage, autoFinish: false, timeLimit: 60, defs: { chess: { t_wall: wall, t_other: other }, enemies: { enemy_t_shooter: shooter } }, kits, units, enemies: [{ key, route }] });
|
||||
h.step();
|
||||
const e = h.enemy(key);
|
||||
assert.ok(h.runUntil(() => e.blockedBy, 30), 'blocked by the wall');
|
||||
h.run(20);
|
||||
checkInvariants(h.b);
|
||||
assert.equal(h.b.errors.length, 0);
|
||||
return { e, h, wall: h.unit('t_wall'), other: withOther ? h.unit('t_other') : null };
|
||||
}
|
||||
|
||||
test('自制投石机 blocked by an operator on the 排气格栅, nobody else in range: no attack', () => {
|
||||
const { e, wall: w } = run({ smog: true });
|
||||
assert.ok(w.s.flags.stealth, 'the smog tile hides the blocker from ranged attacks');
|
||||
assert.equal(e.blockedBy, w);
|
||||
assert.equal(e.stats.attacks, 0);
|
||||
assert.equal(w.stats.taken, 0);
|
||||
});
|
||||
|
||||
test('自制投石机 blocked on the 排气格栅 shoots another operator in its range instead; off the smog it hits its blocker', () => {
|
||||
const a = run({ smog: true, withOther: true });
|
||||
assert.ok(a.e.stats.attacks >= 2);
|
||||
assert.equal(a.wall.stats.taken, 0, 'the hidden blocker is never its target');
|
||||
assert.ok(a.other.stats.taken > 0);
|
||||
const b = run({ smog: false });
|
||||
assert.ok(b.e.stats.attacks >= 2);
|
||||
assert.ok(b.wall.stats.taken > 0, 'a visible blocker is a target as before');
|
||||
});
|
||||
|
||||
test('any other ranged enemy still attacks the operator that blocks it on the 排气格栅 (阻挡优先级最高)', () => {
|
||||
const { e, wall: w } = run({ smog: true, key: 'enemy_t_shooter' });
|
||||
assert.ok(w.s.flags.stealth);
|
||||
assert.ok(e.stats.attacks >= 2 && w.stats.taken > 0);
|
||||
});
|
||||
@@ -0,0 +1,249 @@
|
||||
// test/sim/feedback5-cb4-pins.test.js — community reports of 2026-10-06 that this tree already answers, pinned (DESIGN
|
||||
// §25.18; they pass on the parent commit — nothing changed for them):
|
||||
// item 6 「每局游戏开始展示的敌人类型(折射、飞行等等),实际出现波次在7到9波,而且每个最多三波,其余波次用特异类型填充」 — the
|
||||
// official type schedule (client RandomEnemyGenerater, research 08 §2.1; act2autochess specialEnemyRandomTypeDict count 3,
|
||||
// constData maxLevelCnt 15 / specialEnemyNum 3 / enemyTypeIdentifierToFillRandom 1): each briefing type owns 3 of the
|
||||
// 15 round slots, SPECIAL (特异) the other 6, shuffled — R14 (leader) and R15 (hidden core) take slots too, so the 13
|
||||
// normal rounds hold 7–9 type waves, at most 3 per type;
|
||||
// item 35 「鸭爵策略的悬赏现在有时候会一波出现多只,比如多只鸭子」 — PRTS 下半/PRTS盟约记录 鸭爵 备注 「每回合将有0~2名敌人被
|
||||
// 替换为上述敌人之一」: each player's wave gets 0–2 swaps (bands/meta.js duckReplace), each one of the four at random, so
|
||||
// two ducks in one wave is official (≈ 1 wave in 12 here); never more than 2 per player's wave;
|
||||
// item 29 「会移动的关底boss在各个地图的移动路线复核下是否正确」 — the only leaders that walk are 铳 and 卢西恩 (the 巨型单位 are
|
||||
// 自缚: content/bosses.js SELF_BOUND); their official PATROL_MOVE checkpoints (level_act1autochess_h07_02 route 6,
|
||||
// act2 h07_05: (3,9) → (2,3) → (5,9), looped) are walked on every boss field of the season over walkable tiles only,
|
||||
// the pair's mirrored copy on the right half ((3,11) → (2,17) → (5,11)), and the loop never runs on to the goal;
|
||||
// item 38 「干员野鬃放在红门前两格的时候有概率会把怪顶出地图显示漏怪」 — not reproduced: her pushes (Battle.push → displace)
|
||||
// stop at the rect and at tiles a ground enemy cannot walk, so no pushed enemy stands off the map;
|
||||
// item 39 「锏能拉动10重的关底boss」 — not reproduced: a leader (tag boss) is never displaced (Battle._displaceable), and
|
||||
// her pulls (力度 1 / 2) move no weight ≥ 5 enemy (受力等级 ≤ −3, PRTS 推与拉);
|
||||
// item 47 「昆图斯占地少最左边和最右边两排」 — not reproduced: its hit area is PRTS' 4.95 × 2.95 up 1.0 — 5 × 3 tiles — and an
|
||||
// operator whose range reaches only its leftmost column hits it;
|
||||
// item 52 「最终boss跟原版相比攻击欲望感觉低了」 — every leader attacks at its data interval while a target is in range;
|
||||
// item 57 「囚犯敌人的解放状态联防时不应继承」 — a leaked prisoner re-enters 联防 as a new spawn (unite.js planUnite →
|
||||
// waves.js buildUniteWave: its key and spawn mods only), confined again (archetypes.js prisoner spawn); the freed look
|
||||
// the report saw was 普通 / 老练囚犯's red clip set drawn from the gate, fixed with the prisoners' forms (§25.14.1).
|
||||
// Run: node --test test/sim/feedback5-cb4-pins.test.js
|
||||
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { makeBattle, chessRec, checkInvariants } from '../helpers/battleHarness.js';
|
||||
import { GameData } from '../../server/match/gamedata.js';
|
||||
import { setupMatchWaves, buildUniteWave, buildBossWave, buildNormalWave } from '../../server/match/waves.js';
|
||||
import { bodyKeys } from '../../server/sim/body.js';
|
||||
import { planUnite } from '../../server/match/unite.js';
|
||||
import { createRng } from '../../server/sim/rng.js';
|
||||
import { DATA, makeMatch } from '../match/harness.js';
|
||||
|
||||
test('item 6: the three briefing types fill 7–9 of the 13 normal waves (险境 / 绝境 / 终极), at most 3 each; the rest are SPECIAL', () => {
|
||||
for (const modeId of ['mode_multi_normal', 'mode_single_hard', 'mode_multi_abyss']) {
|
||||
const gd = new GameData(DATA, modeId);
|
||||
assert.equal(gd.bossRound, 14);
|
||||
const totals = new Set();
|
||||
for (let seed = 1; seed <= 200; seed++) {
|
||||
const s = setupMatchWaves(gd, createRng(seed));
|
||||
const normal = s.typeSlots.slice(0, gd.bossRound - 1);
|
||||
const per = s.factions.map((f) => normal.filter((t) => t === f).length);
|
||||
for (const n of per) assert.ok(n >= 1 && n <= 3, `${modeId} seed ${seed}: ${per}`);
|
||||
const total = per.reduce((a, b) => a + b, 0);
|
||||
assert.ok(total >= 7 && total <= 9, `${modeId} seed ${seed}: ${total}`);
|
||||
assert.equal(normal.filter((t) => t === 'SPECIAL').length, normal.length - total, 'every other wave is SPECIAL');
|
||||
totals.add(total);
|
||||
}
|
||||
assert.deepEqual([...totals].sort(), [7, 8, 9], `${modeId}: all three totals occur`);
|
||||
}
|
||||
});
|
||||
|
||||
test('item 57: a prisoner freed in its own combat leaks and re-enters 联防 confined (no freed form, the confinement buff, freed only by its own attacks there)', () => {
|
||||
const KEY = 'enemy_1116_liprr'; // 普通囚犯
|
||||
const wall = chessRec({ id: 't_wall', profession: 'TANK', stats: { atk: 0, maxHp: 1e9, def: 0, blockCnt: 3 }, rangeGrid: [[0, 0]], skill: null });
|
||||
const kits = { t_wall: () => ({ trait: { noAttack: true } }) };
|
||||
const h = makeBattle({ autoFinish: false, timeLimit: 120, defs: { chess: { t_wall: wall } }, kits, units: [{ chessId: 't_wall', row: 9, col: 6 }], enemies: [{ key: KEY, route: 0 }] });
|
||||
assert.ok(h.runUntil(() => h.enemy(KEY) && h.enemy(KEY).form === 'liberty', 60), 'freed by its own attacks');
|
||||
const p = h.enemy(KEY);
|
||||
assert.ok(p.findBuff('ab:liberty') && !p.findBuff('ab:confined'));
|
||||
h.b.retreat(h.unit('t_wall'));
|
||||
assert.ok(h.runUntil(() => !p.alive, 60), 'it walks on and leaks');
|
||||
const r = h.result().perPlayer.p1;
|
||||
assert.deepEqual(r.leaked.filter((l) => l.counted !== false).map((l) => l.enemyKey), [KEY]);
|
||||
checkInvariants(h.b);
|
||||
// 联防: the leaker's counted leak re-enters on the escaped template of one helper
|
||||
const gd = new GameData(DATA, 'mode_multi_normal');
|
||||
const seat = (id, s) => ({ playerId: id, seat: s, deployCount: 1, bonds: {}, layers: {}, board: new Map(), bounties: [] });
|
||||
const m = { isSolo: false, alivePlayers: () => [seat('p1', 1), seat('H', 0)], gd: { unite: { maxHelpers: 2 }, enemy: (k) => gd.enemy(k) } };
|
||||
const plan = planUnite(m, new Map([['p1', r], ['H', { perfect: true, leaked: [], unitsEnd: [] }]]));
|
||||
assert.deepEqual(plan.leaked.map((l) => l.enemyKey), [KEY]);
|
||||
assert.deepEqual(Object.keys(plan.leaked[0]).sort(), ['bounty', 'enemyKey', 'lpr', 'mods', 'sourcePlayerId', 'tag'], 'nothing of its state travels');
|
||||
const wave = buildUniteWave(gd, plan.leaked, 1, 60);
|
||||
const u = makeBattle({
|
||||
kind: 'unite', stageId: 'act1autochess_escaped_single', autoFinish: false, timeLimit: 60, routes: wave.routes,
|
||||
defs: { chess: { t_wall: wall } }, kits, units: [{ chessId: 't_wall', row: 9, col: 8 }],
|
||||
enemies: wave.spawns.map((s) => ({ key: s.enemyKey, time: s.time, route: s.routeIndex, mods: s.mods, sourcePlayerId: s.sourcePlayerId })),
|
||||
});
|
||||
assert.ok(u.runUntil(() => u.enemy(KEY), 30), 're-entered');
|
||||
const q = u.enemy(KEY);
|
||||
assert.equal(q.form ?? null, null, 'drawn confined');
|
||||
assert.ok(q.findBuff('ab:confined') && !q.findBuff('ab:liberty'), 'confined again');
|
||||
assert.ok(u.runUntil(() => q.stats.attacks >= 1, 40), 'blocked, it attacks');
|
||||
assert.equal(q.form ?? null, null, 'still confined after its first 联防 attack');
|
||||
assert.ok(u.runUntil(() => q.form === 'liberty', 60), 'freed again only by its own attacks there');
|
||||
assert.equal(q.stats.attacks, 4, 'at its 4th attack in 联防 (confinement.times), as in a fresh spawn');
|
||||
checkInvariants(u.b);
|
||||
});
|
||||
|
||||
test('item 35: the 鸭爵 strategy swaps 0–2 enemies of each player\'s wave, each one of its four at random (two ducks in one wave included), never more', () => {
|
||||
const hist = [0, 0, 0];
|
||||
let twoSame = 0;
|
||||
for (const seed of [31, 32]) {
|
||||
const h = makeMatch({ mode: 'coop', difficulty: 'NORMAL', seed, fake: true }).start();
|
||||
h.toPrep(6, { band: 'band_ducklord' });
|
||||
for (const ps of h.m.alivePlayers()) {
|
||||
for (let k = 0; k < 40; k++) {
|
||||
const ducks = h.m._normalOpts(ps).spawns.filter((x) => x.tag === 'duck');
|
||||
assert.ok(ducks.length <= 2, `${ducks.length} swaps in one wave`);
|
||||
hist[ducks.length]++;
|
||||
if (ducks.length === 2 && ducks[0].enemyKey === ducks[1].enemyKey) twoSame++;
|
||||
for (const d of ducks) assert.deepEqual(d.bounty, { coins: 1, ownerPlayerId: ps.playerId });
|
||||
}
|
||||
}
|
||||
h.m.dispose();
|
||||
}
|
||||
assert.ok(hist.every((n) => n > 0), `0, 1 and 2 swaps all occur: ${hist}`);
|
||||
assert.ok(twoSame > 0, 'two of the same kind (e.g. two ducks) in one wave occurs');
|
||||
});
|
||||
|
||||
const BIG_POOL = () => ({ hp: 1e12, maxHp: 1e12, damage(pid, a) { this.hp = Math.max(0, this.hp - a); } });
|
||||
const PAIR = [{ playerId: 'p1', seat: 0, side: 'L', units: [], bonds: {} }, { playerId: 'p2', seat: 1, side: 'R', units: [], bonds: {} }];
|
||||
/** A leader field of the real template (the match passes waveId: content/bosses.js templateOf). */
|
||||
function leaderField(bossId, { solo = true, stageId = 'act1autochess_m01', round = 14, mode = 'mode_multi_hard', units = undefined, players = undefined, timeLimit = 600 } = {}) {
|
||||
const gd = new GameData(DATA, mode);
|
||||
const bw = buildBossWave(gd, createRng(5), setupMatchWaves(gd, createRng(1)).factions, round, { bossId, solo });
|
||||
const L = bw.spawns.find((x) => x.tag === 'boss');
|
||||
return makeBattle({
|
||||
kind: round === 15 ? 'hidden' : 'boss', stageId, seed: 3, routes: bw.routes, sharedBoss: BIG_POOL(), autoFinish: false, timeLimit, units,
|
||||
players: players ?? (solo ? undefined : PAIR), enemies: [{ key: L.enemyKey, time: L.time, route: L.routeIndex, mods: L.mods, tag: 'boss' }],
|
||||
setup(b) { b.opts.waveId = bw.templateId; },
|
||||
});
|
||||
}
|
||||
|
||||
test('item 29: 铳 patrols (3,9) → (2,3) → (5,9) on every boss field over walkable tiles (the pair\'s copy the mirrored points); 卢西恩 loops without reaching the goal', () => {
|
||||
const stages = Object.keys(DATA.stages).filter((id) => DATA.stages[id].active !== false && DATA.stages[id].weight > 0);
|
||||
assert.equal(stages.length, 8);
|
||||
for (const stageId of stages) {
|
||||
for (const solo of [true, false]) {
|
||||
const h = leaderField('boss_2', { solo, stageId });
|
||||
const seen = new Map();
|
||||
for (let t = 0; t < 240 * 30; t++) {
|
||||
h.b.step();
|
||||
for (const e of h.b.enemies) {
|
||||
if (!e.alive || !e.isBoss) continue;
|
||||
const r = Math.round(e.y), c = Math.round(e.x);
|
||||
assert.ok(h.b.grid.walkable(r, c, true), `${stageId} ${solo ? 'solo' : 'pair'}: off the road at (${r},${c})`);
|
||||
// the patrol targets in the order it walks them (the leg it is on)
|
||||
const l = seen.get(e.id) ?? []; seen.set(e.id, l);
|
||||
const leg = e.route.legs[e.route.legIdx];
|
||||
const k = leg && leg.r != null ? `${leg.r},${leg.c}` : '-';
|
||||
if (l[l.length - 1] !== k) l.push(k);
|
||||
}
|
||||
}
|
||||
const tracks = [...seen.values()].map((l) => l.join(' '));
|
||||
assert.equal(tracks.length, solo ? 1 : 2, stageId);
|
||||
assert.ok(tracks.some((x) => x.startsWith('3,9 2,3 5,9 3,9')), `${stageId}: ${tracks}`);
|
||||
if (!solo) assert.ok(tracks.some((x) => x.startsWith('3,11 2,17 5,11 3,11')), `${stageId}: the mirrored copy ${tracks}`);
|
||||
checkInvariants(h.b);
|
||||
}
|
||||
}
|
||||
const h = leaderField('boss_5');
|
||||
const leaks = [];
|
||||
h.b.on('enemyLeak', ({ enemy }) => leaks.push(enemy.defId));
|
||||
let wrapped = false;
|
||||
for (let t = 0; t < 420 * 30; t++) { h.b.step(); const e = h.b.enemies.find((x) => x.alive && x.isBoss); if (e && e.route.legIdx === 0 && h.b.time > 300) wrapped = true; }
|
||||
assert.ok(wrapped, '卢西恩 starts its patrol again after its 19 checkpoints');
|
||||
assert.deepEqual(leaks, []);
|
||||
});
|
||||
|
||||
test('item 38: 野鬃\'s pushes towards the red gate never leave a ground enemy off the map (real waves, S2 running)', () => {
|
||||
const gd = new GameData(DATA, 'mode_single_hard');
|
||||
const setup = setupMatchWaves(gd, createRng(2));
|
||||
let pushes = 0;
|
||||
for (const r of [6, 12]) {
|
||||
const w = buildNormalWave(gd, createRng(200 + r), setup.factions, r);
|
||||
for (const [row, col] of [[9, 8], [12, 8], [12, 9]]) {
|
||||
const h = makeBattle({ stageId: 'act1autochess_m01', seed: 2, routes: w.routes, timeLimit: w.timeLimit, units: [{ chessId: 'chess_char_1_19_b', row, col, dir: 'RIGHT' }],
|
||||
enemies: w.spawns.map((x) => ({ key: x.enemyKey, time: x.time, route: x.routeIndex, count: x.count, interval: x.interval, mods: x.mods })) });
|
||||
const u = h.unit('chess_char_1_19_b');
|
||||
h.step();
|
||||
h.b.on('tick', () => {
|
||||
if (u.alive && u.skill && !u.skill.active) u.skill.gainSp(999, 'test');
|
||||
for (const e of h.b.enemies) {
|
||||
if (!e.alive || e.hidden || e.isFlying) continue;
|
||||
assert.ok(h.b.grid.walkable(Math.round(e.y), Math.round(e.x), true), `R${r} (${row},${col}): ${e.defId} off the map at (${e.y.toFixed(2)},${e.x.toFixed(2)})`);
|
||||
}
|
||||
}, { priority: -1000 });
|
||||
const orig = h.b.push.bind(h.b);
|
||||
h.b.push = (...a) => { const m = orig(...a); if (m > 0) pushes++; return m; };
|
||||
h.runToEnd(200);
|
||||
assert.equal(h.b.errors.length, 0, JSON.stringify(h.b.errors[0]));
|
||||
checkInvariants(h.b);
|
||||
}
|
||||
}
|
||||
assert.ok(pushes >= 60, `she pushed (${pushes} pushes)`);
|
||||
});
|
||||
|
||||
test('item 39: 锏\'s S3 never moves a leader (every leader of the season), nor any weight-10 enemy', () => {
|
||||
for (const bossId of ['boss_1', 'boss_4', 'boss_6', 'boss_7']) {
|
||||
const h = leaderField(bossId, { units: [{ chessId: 'chess_char_6_19_b', row: 9, col: 7, skillIndex: 3 }] });
|
||||
h.step();
|
||||
const u = h.unit('chess_char_6_19_b');
|
||||
const boss = h.b.enemies.find((e) => e.isBoss);
|
||||
boss.mods = { ...(boss.mods || {}), speedMul: 0 };
|
||||
boss.markDirty?.();
|
||||
const at = [boss.x, boss.y];
|
||||
let moved = 0;
|
||||
const orig = h.b.displace.bind(h.b);
|
||||
h.b.displace = (e, ...a) => { const m = orig(e, ...a); if (e === boss) moved += m; return m; };
|
||||
for (let t = 0; t < 40 * 30; t++) { h.b.step(); if (u.alive && u.skill && !u.skill.active) u.skill.gainSp(999, 'test'); }
|
||||
assert.ok(u.skill.activations >= 3, `${bossId}: S3 cast`);
|
||||
assert.equal(boss.s.massLevel, 10);
|
||||
assert.equal(moved, 0, `${bossId}: never displaced`);
|
||||
assert.deepEqual([boss.x, boss.y], at);
|
||||
}
|
||||
// a weight-10 enemy that is no leader (自在 as a bounty): 力度 2 − 10 ⇒ no pull
|
||||
const h = makeBattle({ autoFinish: false, timeLimit: 30, units: [{ chessId: 'chess_char_6_19_b', row: 10, col: 6 }], enemies: [{ key: 'enemy_1517_xi', pos: [10, 8], mods: { speedMul: 0 } }] });
|
||||
h.step();
|
||||
const xi = h.enemy('enemy_1517_xi');
|
||||
assert.equal(xi.s.massLevel, 10);
|
||||
assert.equal(h.b.pull(xi, 2, { to: { x: 6, y: 10 } }), 0);
|
||||
assert.equal(h.b.pull(xi, 5, { to: { x: 6, y: 10 } }), 0, 'not even 特大力');
|
||||
});
|
||||
|
||||
test('item 47: 昆图斯 occupies 5 × 3 tiles (PRTS 4.95 × 2.95, up 1.0); an operator reaching only its leftmost column hits it', () => {
|
||||
const h = makeBattle({ kind: 'boss', stageId: 'flat', sharedBoss: BIG_POOL(), autoFinish: false, timeLimit: 30,
|
||||
units: [{ chessId: 'chess_char_1_12_a', row: 10, col: 7 }], enemies: [{ key: 'enemy_1521_dslily', pos: [3, 10], mods: { speedMul: 0 }, tag: 'boss' }] });
|
||||
h.step();
|
||||
const boss = h.b.enemies.find((e) => e.isBoss);
|
||||
const tiles = bodyKeys(boss).map((k) => [Math.floor(k / 21), k % 21]);
|
||||
assert.deepEqual([...new Set(tiles.map((t) => t[1]))], [8, 9, 10, 11, 12], '5 columns');
|
||||
assert.deepEqual([...new Set(tiles.map((t) => t[0]))], [3, 4, 5], '3 rows (up 1.0)');
|
||||
const u = h.unit('chess_char_1_12_a');
|
||||
assert.deepEqual([u.tileR, u.tileC], [3, 7]);
|
||||
h.run(8);
|
||||
assert.ok(u.stats.attacks >= 3, `艾丝黛尔 next to its leftmost column attacks it (${u.stats.attacks})`);
|
||||
});
|
||||
|
||||
test('item 52: each leader attacks at its data interval while it has a target (150 s, walls in range)', () => {
|
||||
const units = [[9, 3], [10, 4], [11, 5], [12, 6], [9, 8], [10, 9], [12, 9], [11, 8]].map(([row, col], i) => ({ chessId: `t_w${i}`, row, col }));
|
||||
const chess = {}, kits = {};
|
||||
units.forEach((x) => { chess[x.chessId] = chessRec({ id: x.chessId, profession: 'TANK', stats: { atk: 1, maxHp: 1e9, def: 300, res: 30, blockCnt: 3 }, rangeGrid: [[0, 0]], skill: null }); kits[x.chessId] = () => ({ trait: { noAttack: true } }); });
|
||||
for (const bossId of ['boss_1', 'boss_4', 'boss_6', 'boss_7']) {
|
||||
const gd = new GameData(DATA, 'mode_multi_hard');
|
||||
const bw = buildBossWave(gd, createRng(5), setupMatchWaves(gd, createRng(1)).factions, 14, { bossId, solo: true });
|
||||
const L = bw.spawns.find((x) => x.tag === 'boss');
|
||||
const h = makeBattle({ kind: 'boss', stageId: 'act1autochess_m01', seed: 3, routes: bw.routes, sharedBoss: BIG_POOL(), autoFinish: false, timeLimit: 160,
|
||||
defs: { chess }, kits, units, enemies: [{ key: L.enemyKey, time: L.time, route: L.routeIndex, mods: L.mods, tag: 'boss' }], setup(b) { b.opts.waveId = bw.templateId; } });
|
||||
h.run(150);
|
||||
const boss = h.b.enemies.find((e) => e.isBoss);
|
||||
const max = Math.floor(150 / boss.s.interval);
|
||||
assert.ok(boss.stats.attacks >= max - 1, `${bossId} ${L.enemyKey}: ${boss.stats.attacks} attacks, ${max} at its ${boss.s.interval} s interval`);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
// test/sim/feedback5-raid-own-board.test.js — 突袭 lands only on its player's own board (community reports of
|
||||
// 2026-10-06, items 40 and 16.3; DESIGN §25.18):
|
||||
// 「…新约能天使在开了突袭之后蹦到了下方原本用来临时放置溢出的干员和道具的那一栏高台的最左侧位置」 — on a boss field the
|
||||
// battle rect (BOSS_RECT rows 0–5) holds the hand row (0) and the 临时整备区 row (1), high ground buildable ALL, so a
|
||||
// ranged member could land there;
|
||||
// 「单人联防时突袭也可以跑到对面的场地上」 — on the 联防 map of one helper (escaped_single) the right half (cols 11–18)
|
||||
// is in the rect but is nobody's board.
|
||||
// raidTile now takes only tiles of Battle.onOwnBoard: the board region (rows 9–12, cols 2–10) mapped onto the field.
|
||||
// Run: node --test test/sim/feedback5-raid-own-board.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';
|
||||
|
||||
const ID = 'chess_char_6_13_a'; // 新约能天使 (RANGED), given the 突袭 bond as the 转职球 / 突袭手雷 would
|
||||
const raw = getDefaultSource().rawChess(ID);
|
||||
const raider = { ...raw, bonds: [...raw.bonds, 'raidShip'] };
|
||||
const BONDS = { raidShip: { count: 2, active: true, tier: 1, layers: 0 } };
|
||||
const dummy = enemyRec({ key: 'dummy', hp: 1e9, speed: 0, mass: 0 });
|
||||
const defs = { enemies: { dummy }, chess: { [ID]: raider } };
|
||||
|
||||
function jump({ kind, stageId, players, enemyPos, seconds = 11 }) {
|
||||
const h = makeBattle({ kind, stageId, autoFinish: false, timeLimit: 60, defs, players });
|
||||
h.step();
|
||||
const mine = h.b.allyUnits.filter((u) => u.defId === ID);
|
||||
const homes = mine.map((u) => [u.tileR, u.tileC]);
|
||||
h.spawn('dummy', { pos: enemyPos });
|
||||
h.run(seconds);
|
||||
checkInvariants(h.b);
|
||||
assert.equal(h.b.errors.length, 0, JSON.stringify(h.b.errors[0]));
|
||||
return { h, mine, homes };
|
||||
}
|
||||
const seat = (playerId, s, o = {}) => ({ playerId, seat: s, side: o.side ?? 'L', colOffset: o.colOffset ?? 0, bonds: BONDS, units: o.units ?? [] });
|
||||
const unitAt = (row, col, uid = 1) => ({ uid, kind: 'chess', chessId: ID, row, col });
|
||||
|
||||
test('boss field (solo 最终攻势): a ranged 突袭 member never lands on the hand row 0 or the 临时整备区 row 1', () => {
|
||||
// 战场#01: the enemy on the telin (1,3); before the fix the member landed on the hand tile (0,3)
|
||||
const { h, mine } = jump({ kind: 'boss', stageId: 'act1autochess_m01', players: [seat('p1', 0, { units: [unitAt(12, 3)] })], enemyPos: [1, 3] });
|
||||
const u = mine[0];
|
||||
assert.deepEqual([u.tileR, u.tileC], [2, 3], 'the board tile next to it, not (0,3)');
|
||||
assert.ok(h.b.onOwnBoard(u.player, u.tileR, u.tileC));
|
||||
// every row-0 / row-1 tile is off the board, every board tile (rows 2–5, cols 2–10) is on it
|
||||
for (let c = 0; c <= 20; c++) for (const r of [0, 1]) assert.equal(h.b.onOwnBoard(u.player, r, c), false, `(${r},${c})`);
|
||||
for (let r = 2; r <= 5; r++) for (let c = 2; c <= 10; c++) assert.equal(h.b.onOwnBoard(u.player, r, c), true, `(${r},${c})`);
|
||||
for (let r = 2; r <= 5; r++) for (let c = 11; c <= 20; c++) assert.equal(h.b.onOwnBoard(u.player, r, c), false, `(${r},${c}) is the right half`);
|
||||
// an enemy only the temp row could reach: it stays home and does not hop
|
||||
const far = jump({ kind: 'boss', stageId: 'act1autochess_m01', players: [seat('p1', 0, { units: [unitAt(12, 3)] })], enemyPos: [0, 9] });
|
||||
assert.deepEqual([far.mine[0].tileR, far.mine[0].tileC], far.homes[0]);
|
||||
});
|
||||
|
||||
test('boss field pair: the mirrored right player lands on its own half only', () => {
|
||||
const { h, mine } = jump({
|
||||
kind: 'boss', stageId: 'act1autochess_m01',
|
||||
players: [seat('p1', 0), seat('p2', 1, { side: 'R', units: [unitAt(12, 3)] })], enemyPos: [3, 9],
|
||||
});
|
||||
const u = mine[0];
|
||||
assert.equal(u.ownerId, 'p2');
|
||||
// the enemy stands on the partner's half next to the middle: the member takes a tile of its own half that reaches it
|
||||
// (before the fix: (2,9), the partner's road)
|
||||
assert.ok(u.tileR >= 2 && u.tileC >= 10, `landed on (${u.tileR},${u.tileC})`);
|
||||
assert.ok(h.b.onOwnBoard(u.player, u.tileR, u.tileC));
|
||||
assert.equal(h.b.onOwnBoard(u.player, 3, 5), false, 'the left half is the partner\'s');
|
||||
assert.equal(h.b.onOwnBoard(u.player, 3, 15), true);
|
||||
});
|
||||
|
||||
test('联防 with one helper (escaped_single): 突袭 does not jump onto the right half', () => {
|
||||
for (const pos of [[10, 15], [11, 17], [9, 12]]) {
|
||||
const { h, mine, homes } = jump({ kind: 'unite', stageId: 'act1autochess_escaped_single', players: [seat('H', 0, { units: [unitAt(12, 9)] })], enemyPos: pos });
|
||||
const u = mine[0];
|
||||
assert.ok(u.tileC <= 10, `enemy ${pos}: landed on (${u.tileR},${u.tileC})`);
|
||||
assert.ok(h.b.onOwnBoard(u.player, u.tileR, u.tileC), `enemy ${pos}`);
|
||||
if (pos[1] >= 13) assert.deepEqual([u.tileR, u.tileC], homes[0], `enemy ${pos}: out of reach from the left half, it stays`);
|
||||
}
|
||||
// an enemy the left half can reach: it still jumps (onto the left half)
|
||||
const { mine } = jump({ kind: 'unite', stageId: 'act1autochess_escaped_single', players: [seat('H', 0, { units: [unitAt(12, 3)] })], enemyPos: [9, 9] });
|
||||
assert.ok(mine[0].tileC <= 10 && mine[0].tileC >= 7, `landed on (${mine[0].tileR},${mine[0].tileC})`);
|
||||
});
|
||||
|
||||
test('联防 with two helpers (escaped_multi): each helper lands on its own half', () => {
|
||||
const players = [seat('L', 0, { units: [unitAt(12, 3, 1)] }), seat('R', 1, { colOffset: 8, units: [unitAt(12, 9, 2)] })];
|
||||
const { h, mine } = jump({ kind: 'unite', stageId: 'act1autochess_escaped_multi', players, enemyPos: [10, 15] });
|
||||
const right = mine.find((u) => u.ownerId === 'R'), left = mine.find((u) => u.ownerId === 'L');
|
||||
assert.ok(right.tileC >= 11, `the right helper lands on its half: (${right.tileR},${right.tileC})`);
|
||||
assert.ok(h.b.onOwnBoard(right.player, right.tileR, right.tileC));
|
||||
assert.ok(left.tileC <= 10, `the left helper stays on its half: (${left.tileR},${left.tileC})`);
|
||||
});
|
||||
Reference in new issue
Block a user