feedback5: merge W5L — Touch per PRTS (S3 extra heal, below-half boost, 攫升 on any heal, 超脱 on dying forced exits), 突袭 counts an active passive as 技能就绪 (#49), 生命回复速度 effects are hpRegen, not heals (#96 / #137; the separation proposed in PR #135)

This commit is contained in:
sganggs committed 2026-10-05 22:49:35 +08:00
commit 5c7cb08afe
37 files changed
+1495 -1102

No files matched your search

+1
View File
@@ -74,6 +74,7 @@
- 开战时干员按**逐列从左到右、每列从上到下**的顺序部署(最左一列最先,与阿戈尔吞噬「更靠左和靠上」的顺序相同),召唤物在所有干员之后。被阻挡的敌人先打阻挡它的干员;没被阻挡的远程敌人先打嘲讽等级高的,同级时打最后部署的(召唤物、最右一列靠下的干员和刚再部署的干员更容易挨打)。隐匿的干员只会被它阻挡的敌人攻击,没被它挡住的敌人的溅射、爆炸、范围技能、留下的伤害区域(包括假想敌:蚀裂被击倒后喷出的毒雾)以及深池伙友卫队、扎罗的减攻速光环也落不到它身上(和官方一样;写明「无视无法选择」的效果如污染秽蚀照常能打到,寒霜的减攻速光环和“墓碑”这类地图效果照常生效);**迷彩**(如忍冬三技能期间击倒敌人后、寒芒克洛丝一技能)同样只会被它阻挡的敌人攻击,也显示为半透明,但躲不开溅射、爆炸和范围伤害(同时打范围内所有单位的普通攻击——如“斩胄之剑”“破胄之锤”“灵幛”——打不到它),也不算隐匿(不触发叙拉古等「隐匿时」效果)。叙拉古的隐匿按时(32 秒 + 每层 0.4 秒)结束;忍冬的迷彩按官方持续到她下一次开技能。**蒂比起飞**期间只挡飞行敌人,地面敌人不会选她为目标(普通攻击、溅射、技能范围、燃烧区域和要选中目标的减益都落不到她身上);飞行和悬浮敌人、写明「无视无法选择」的效果(如污染秽蚀)照常能打到她;地面敌人的光环和全场效果(如“墓碑”让全场攻击力、防御力减半)、她攻击敌人时招来的反制(如重装侦察兵的暴露)照常生效,起飞前已挂上的持续伤害也照常跳。
- **技能自动释放**按官方「技能策略」:一般的手动技能在技能就绪、即将攻击 / 治疗且初始攻击范围内有敌人(治疗技能:有受伤的队友)时释放;**带独立技能范围**的技能(如德克萨斯「剑雨」、凛御银灰「御敌的锋锐」、锏「归于宁静」,不含「攻击范围扩大」类)在**技能范围内出现敌人**时就释放,不必先攻击;**开启后攻击范围比平时大**的手动技能(如莫斯提马「序时之匙」、银灰「真银斩」、史尔特尔「黄昏」、白面鸮「脑啡肽」)在**开启后的攻击范围内出现敌人**(治疗技能:有受伤的队友)时就释放,不必等敌人走进平时的攻击范围,这是本作按玩家反馈有意与官方不同的地方;**重装干员**的手动技能在受到伤害时释放(例外:深巡、雷蛇的二技能,号角的二、三技能,灰毫的一、二技能按玩家反馈改为攻击范围内有敌人时就释放(深巡二技能按开启后更远的攻击范围判断),余的二技能「厚礼上宾」改为周围两格(技能范围)内有敌人时就释放,这是本作有意与官方不同的地方;深巡一技能仍要受到伤害);执旗手 / 战术家 / 吟游者技能就绪即释放,解放者 / 阵法术师在初始攻击范围内有敌人时释放(开启后攻击范围扩大的技能——薄绿「风语」、蜜蜡「沙暴扩散」、卡涅利安「食噬之印」、玛恩纳「未宽解的悲哀」,以及安洁莉娜「秘杖·反重力模式」——同样按开启后的攻击范围判断)。**自动触发**的技能按其本身规则:只作用于队友的(如引星棘刺「度算浪波」、浊心斯卡蒂「同葬无光之愿」、纯烬艾雅法拉「无声润物」)技力满就释放,不用等敌人或伤员;伺夜「领袖的呼唤」「领袖的馈赠」只在场上有狼群时释放:狼群处于战术点形态时,「领袖的呼唤」也会释放并让它立刻带着 1 只狼影回到场上(狼影未满时改为加 1 只狼影,已满时把狼群的生命值回满),「领袖的馈赠」则要等狼群回来;又如古米「备用军粮」在身边(技能范围内)有受伤的队友时就会发动,下一次攻击改为治疗该队友(不用先接敌;她的二技能「食粮烹制」是手动技能,按重装规则在受到伤害时释放);塞雷娅「急救」在她即将攻击时、身边有生命不高于一半的队友才发动,这次攻击直接改为治疗;新约能天使二技能的护盾按官方给攻击范围内**仇恨最高**的队友(嘲讽等级高的优先,同级时给最后部署的),不一定是站在最前面挨打的那个。手动技能的自动释放有 3 秒冷却:开战部署后先等 3 秒,之后同一干员两次自动释放至少间隔 3 秒(可充能的技能不会同时放完)。
- **推开 / 拉拽**按官方「力度 − 重量」决定距离:例如野鬃二技能(中等力度)把重量 0 / 1 / 2 / 3 的敌人推开约 2.1 / 1.7 / 0.4 / 0.1 格,重量 4 以上推不动——轻型敌人反而推得更远。野鬃二技能沿她的朝向推开:正前方 45° 以内按上面的距离,身后、侧面或贴身的敌人只被轻推一下(约 0.4 格以内);琳琅诗怀雅三技能的金币则从她身边向外推开,落在她前方 2–4 格的范围(官方「范围2-4」)内的地面敌人和她阻挡的敌人身上。攻击速度最低为 20(沼泽、寒霜等减速叠满时也不会更慢)。
- **生命回复不是治疗**(与官方一致):吟游者的特性(魔王、浊心斯卡蒂及其海嗣)、调香师的天赋、瑕光二技能、铃兰三技能、锡人炼金单元给友军的「每秒恢复生命」是提高对方的**生命回复速度**,不是治疗:收割者 / 不屈者 / 武者(如隐德来希、圣约送葬人、折桠)这类「无法被友方治疗」的干员和处于禁疗的干员也能吃到,治疗量加成(如「受到的治疗效果提升」)也不会放大它;铃兰三技能开启后的第一秒没有回复。直接治疗(医疗干员的治疗、技能的「恢复…生命」)仍然对这些干员无效。
- **元素损伤条**在单位自己的血条正下方:左边是元素图标,白条是剩余的元素值,只有真正爆发时才会耗尽;爆发后条变成元素的颜色、图标闪烁,在冷却期间慢慢回满(这段时间不会再积累元素损伤)。
- **敌人**:远程敌人的射程按官方从干员的碰撞体积(半径 0.25 格)算起,比数据上的攻击范围半径远 0.25 格——例如萨卡兹枯朽战车(射程 2.2)能打到中心 2.45 格以内、站在低地的干员。没被阻挡的远程敌人每次攻击都会站定、播完攻击动作,两次攻击之间才继续前进。它的第一下攻击就是「秽蚀轰击」(在目标处留下半径 1.7、持续 10 秒的污染区:低地每秒 50、高台 25 点真实伤害,同名不叠加),被阻挡时普通攻击伤害翻倍。“萨科塔之翼”等血量第一次低于一半时会在原地小范围乱飞 5 秒(官方叫「恐惧」);叙拉古、妮芙等干员造成的恐惧会让敌人朝远离干员的方向逃跑。隐匿的敌人只有被阻挡(或被揭示)时才能被选为攻击目标,溅射、技能的圆形范围伤害也打不到没被挡住的隐匿敌人(和官方一样);阻挡解除后 3 秒内它仍然可以被选中(官方页面注明 0 秒或 1 秒的敌人按页面),之后才重新隐匿:深池逐火战士每次被击倒后先重生 1 秒,然后变成继续往前走的隐匿「余烬」(需要 5 次伤害击倒,护卫的「火灰」10 次),一般要用干员挡住它才能选中(挡住时它不再半透明;被阻挡时被击倒的,重生结束后约 2 秒内也能用远程或范围伤害补刀),10 秒内没打掉就满血站起来;敌人重生时身上的减速、恐惧等状态会被清空、技能冷却从头开始,被恐惧的逐火战士变成余烬后也能被挡住;转译基底·α 原始形态受到的伤害全部无效,受到第 4 次物理伤害、第 4 次法术伤害或被阻挡时花 2 秒变成寻仇者、特战术师或幽灵,之后才能被击倒。
- **策略「鸭爵」(“神秘顾客”)**:从第 5 回合起,你和队友的每场作战(**最终攻势和隐秘核心也算**,联防不另外替换)有 0–2 名地面敌人(不含领袖及其部件、悬赏敌人)被替换为特殊版本的鸭爵、高普尼克、流泪小子或圆仔,出现在被替换敌人的时间和路线上(两人同场的领袖战里,各自只替换走向自己保护目标点的敌人);击倒者获得 1 资金(联防中的队友也算),漏进保护目标点照常扣 1 点目标生命值。鸭爵和圆仔**不攻击、无法被阻挡**:鸭爵受到伤害后移动速度 +300%;圆仔始终面向我方干员较多的一侧,来自正面的物理 / 法术伤害 −80%。流泪小子隐匿(被阻挡时才能被选中),攻击使目标晕眩 3.5 秒;高普尼克免疫晕眩、冻结和浮空。
+13 -5
View File
@@ -95,7 +95,9 @@ where it fell for the `kill` / `death` handlers. "倒地干员所在地块视为
tile and `isReservedTile` reports it, so every automatic picker skips it. The rule covers every 退场 (GitHub #60): an
operator forced out by its own effects (`retreat` reason `'retreat'`: 史尔特尔's 余烬, 耀骑士临光 S2, 骑士戒律 + 竞技旗,
伊内丝 S3; `'merchant'`: a 商人 that cannot pay) lies down and comes back the same way — still no kill (its death reason is
not `'killed'`: no 被击倒 effects, 阿戈尔 or knock-down count), but 不屈 rolls on it (PRTS 盟约记录 不屈 修正 "被击倒、撤退、
not `'killed'`: no 被击倒 effects, 阿戈尔 or knock-down count — except Touch's 超脱 on a `dying` exit, a knock-out put off
by the operator's own effect that plays its death animation: 史尔特尔's 余烬, 骑士戒律 + 竞技旗; PRTS Touch(卫戍协议) 备注
"部分有死亡动画的强制撤退(如史尔特尔的天赋效果)也能触发这一天赋"), but 不屈 rolls on it (PRTS 盟约记录 不屈 修正 "被击倒、撤退、
切换<替身>与<本体>时": a hit redeploys it at once, free, where it lies; addon/battle.js); only the 突袭 retreat (`'raid'`,
redeployed at once on its landing tile — no 不屈 roll) and permanent removals leave nothing.
@@ -683,7 +685,13 @@ unit at ≥ 1 HP) → **`damaged`** → SP-on-hurt / TAKE_DAMAGE → `kill` + `d
`battle.heal(source, target, amount, { overheal=false, self, silent, regen, ignoreHealFree })`: no-op on `noHeal` targets
(unless self — 禁疗 / 孤立 summons carry the flag, §3) and on `healFree` ones, self included (史尔特尔's 余烬), unless `regen`
(an HP-regen attribute tick) or `ignoreHealFree` (a heal that "无视禁疗");
× source `healingDealtMul` × target `healingTakenMul`; **`heal`** hook (mutable amount); capped at max HP; `overheal`
× source `healingDealtMul` × target `healingTakenMul`; **`heal`** hook (mutable amount); capped at max HP; a `regen` tick
— the unit's own 生命回复速度 (`s.hpRegen`, applied in the buffs phase) — is no 治疗 (PRTS 调香师 / 瑕光 / 铃兰 / 锡人 备注
"不受治疗加成和禁疗影响"): no multiplier, and the hook sees it (`opts.regen`) but cannot change its amount. Effects PRTS
describes as raising the target's 生命回复速度 are hpRegen buffs, never `heal` calls, so 禁疗 and 无法被友方治疗 (`noHeal`:
收割者 / 不屈者 / 武者) do not stop them: the 吟游者 trait (professions.js `bardRegen`, 分支特性信息 吟游者; 魔王's 微尘 ×1.5
through its `bardRegen` hook; 浊心斯卡蒂 and her 海嗣), 调香师's 熏衣草, 瑕光 S2, 铃兰 S3 (none in its first second, refreshed
every second), 锡人's 炼金单元 (GitHub #96 / #137); `overheal`
turns the excess into an `overheal` shield. `battle.loseHp(target, amount, { source, from, tags, silent, sourceless })` = HP
loss ignoring DEF/RES/shields/dodge (流失); `sourceless: true` makes it 无来源 ("受到等量的无来源生命流失": hooks see no source,
`source` keeps the credit — stats and the per-player shared-pool tally), as does a 无来源 `from`. A 流失 skips the damage
@@ -732,7 +740,7 @@ registration order. `battle.off(handle)` / `battle.off(name, fn)` / `battle.offO
| `dollSwitch` | `{ unit, reason, done }` | content switches a 傀儡师 to its <替身> now (归溟幽灵鲨 S2 "技能结束后立刻切换为<替身>": no lethal HP loss); its trait does it unless it already is one or is not on the field, and sets `done` |
| `dollSwap` | `{ unit, form }` | a 傀儡师 starts a switch — to its <替身> (`form` `'doll'`) or back to its <本体> (`null`); not when it is knocked out as the 替身 (不屈 rolls on it: "切换<替身>与<本体>时") |
| `kill` | `{ killer, victim }` | victim HP reached 0 (a handler may revive by restoring HP) |
| `death` | `{ unit, reason:'killed'|'leak'|'retreat'|'merchant'|'expired'|'forcedExit', killer }` | unit removed (`'forcedExit'`: an operator entering 联防 knocked out, §1.1) |
| `death` | `{ unit, reason:'killed'|'leak'|'retreat'|'merchant'|'expired'|'forcedExit', killer, dying }` | unit removed (`'forcedExit'`: an operator entering 联防 knocked out, §1.1; `dying`: a `retreat` that plays the death animation — 史尔特尔's 余烬, 骑士戒律 + 竞技旗) |
| `skillStart` / `skillEnd` | `{ unit, skill, reason }` | mutate `skill.ammoLeft` / `skill.timeLeft` in skillStart (bullets added there raise `skill.ammoMax`, the ammo bar's full mark) |
| `ammoUsed` | `{ unit, left, skill }` | per ammo consumed |
| `spGain` | `{ unit, amount, reason:'time'|'attack'|'hurt'|'init'|…, skill }` | mutable `amount` (time gains fire every tick) |
@@ -777,7 +785,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) |
| `addDp(playerId, n)`, `retreat(unit, {reason, permanent})`, `relocate(unit, r, c)` | `relocate` only changes the tile (state kept, no event) |
| `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 |
| `refreshRange(unit)`, `setExtraRange(unit, keys)`, `rangeChanged(unit)` | rebuild the ranges after changing `unit.rangeGrid` (流形 copies); extra targetable tiles (absolute keys; merged into every later rebuild until set again; `null` clears; never in `baseRangeKeys`): 蕾缪安 wanted, 维娜 S3 |
@@ -1154,7 +1162,7 @@ table: `hitSleep` (targets and damages sleeping enemies — "可以攻击沉睡
| wandermedic | heal + reduce element gauges by 50 % ATK (bb ep_heal_ratio); also targets uninjured allies with gauge |
| incantationmedic | arts attack; EVERY damage the unit deals heals the lowest ally in range for 50 % (bb scale) of it — the official trait buff (`vendla_tr` / `reed2_tr` / `titi_tr`) is ON_AFTER_OUTPUT_DAMAGE, so skill and DoT damage heals too (缇缇's 凝固的时光 ticks, 焰影苇草's S2 fireballs while she is disarmed); a skill that triggers it for one named ally says so ("仅对该角色触发…特性") and the damage instance carries that ally (`DamageInfo.traitAlly`) |
| slower | sluggish 0.8 s on hit (bb sluggish) |
| bard | no attack; every second heals allies in range 10 % ATK (bb atk_to_hp_recovery_ratio) |
| bard | no attack; allies in range get 生命回复速度 +10 % ATK (bb atk_to_hp_recovery_ratio) — an hpRegen buff refreshed every 0.25 s (`bardRegen`), no heal |
| craftsman | melee phys (support devices via kit) |
| shotprotector | ranged phys, can hit FLY, blocks 3 |
| fortress | melee single target while blocking, ranged 1.0 splash otherwise, ground only (never hits FLY) |
+1 -1
View File
@@ -920,7 +920,7 @@ Members (5 chess, 4 in current shop pool; by tier in shop: {'2': 1, '3': 1, '5':
**Implementable spec**
- **[2 distinct]** If a 突袭 member has not attacked for 10 s, or its skill is ready, and no enemy is in its range: it is immediately redeployed (keeping SP) onto a tile next to a ground enemy; while in that redeployed state its ATK and maxHP x(1 + 0.25 + 0.01*L).
- **[2 distinct]** If a 突袭 member has not attacked for 10 s, or its skill is ready, and no enemy is in its range: it is immediately redeployed (keeping SP) onto a tile next to a ground enemy; while in that redeployed state its ATK and maxHP x(1 + 0.25 + 0.01*L). A passive skill that is on counts as ready (GitHub #49: the reporter's footage shows 缄默德克萨斯 jumping within her passive's 10 s; the engine keeps a passive on for the whole deployment [ASSUMED]); the landing tile must have the target in range (GitHub #51 [ASSUMED]).
- **[L >= 50]** ALL operators ASPD +50.
- Formulas: `atkHpMultiplier = 1.25 + 0.01*L`; `idleSec = 10`; `aspdAll(L>=50) = 50`
- How layers are gained: 史尔特尔 部署时 +8 (<=50/battle); 休谟斯 each 2 kills +1; 瑕光 +4/deploy; 斯卡蒂; 伊内丝 +5; 机变 "斯卡蒂的盟誓" +8, "德克萨斯的盟誓" +10.
+6 -4
View File
@@ -86,13 +86,15 @@ export class BattleDeploy {
/**
* Withdraw an ally without a kill (it may redeploy after its respawn time): an operator lies down where it stood and
* comes back there (isDown, GitHub #60) — unless `permanent`, or the 突袭 retreat ('raid') that redeploys it at once.
* `dying`: a forced exit that plays the operator's death animation — a knock-out put off by its own effect (史尔特尔's
* 余烬, 骑士戒律 + 竞技旗); the `death` hook carries it (Touch's 超脱 counts such an exit: content/tokens.js).
*/
retreat(unit, { reason = 'retreat', permanent = false } = {}) {
retreat(unit, { reason = 'retreat', permanent = false, dying = false } = {}) {
if (!unit || !unit.alive || unit.side !== 'ally') return;
this._remove(unit, reason, null, permanent);
this._remove(unit, reason, null, permanent, dying);
}
_remove(unit, reason, killer = null, permanent = false) {
_remove(unit, reason, killer = null, permanent = false, dying = false) {
unit.alive = false;
unit.removeReason = reason;
unit.deployed = false;
@@ -145,7 +147,7 @@ export class BattleDeploy {
}
// the reason ('killed' | 'retreat' | 'expired' | …) lets the client keep the knock-down sound for real knock-outs
if (reason !== 'leak') this._ev(['die', unit.id, reason]);
if (this._hooks.death) this.emit('death', { unit, reason, killer });
if (this._hooks.death) this.emit('death', { unit, reason, killer, dying: !!dying });
if (unit.removed) this._toRelease.push(unit);
}
+4 -3
View File
@@ -185,9 +185,10 @@ export class BattleTiles {
* decision of 2026-10-04): knocked out ('killed'), entering the battle knocked out (FORCED_EXIT, 联防) and forced out
* by its own effects ('retreat': 史尔特尔's 余烬, 耀骑士临光 S2, 骑士戒律 + 竞技旗, 伊内丝 S3; 'merchant': a 商人 that cannot
* pay) — except the 突袭 retreat ('raid', redeployed at once on its landing tile); not removed for good, after it was
* deployed. A forced exit stays no kill: its 'die' / `death` reason is not 'killed' (no 被击倒 effect, 不屈, 阿戈尔, no
* knock-down count). The client keeps its model on that tile knocked down with a redeploy countdown (b.snap `down`,
* render/units.js); summons, devices and enemies simply leave.
* deployed. A forced exit stays no kill: its 'die' / `death` reason is not 'killed' (no 被击倒 effect, 阿戈尔, no
* knock-down count — but 不屈 rolls on it, and Touch's 超脱 counts a `dying` one: 史尔特尔's 余烬, 骑士戒律 + 竞技旗). The
* client keeps its model on that tile knocked down with a redeploy countdown (b.snap `down`, render/units.js); summons,
* devices and enemies simply leave.
*/
isDown(u) {
return !!u && u.side === 'ally' && u.kind === 'op' && !u.alive && !u.removed && u.removeReason !== 'raid'
+9 -2
View File
@@ -30,7 +30,8 @@
// 无来源 damage uses the chance and hits nobody, a 流失 never does — PRTS 备注 / 作战机制)
// + 脆弱 ×damage_scale for weak[limit] s
// 助力 deputShip all operators DEF +(base + per·L), redeploy time ×(1 + respawn_time)
// 突袭 raidShip member idle ≥ no_attack_duration s (or skill ready) with no enemy in range → "保留技力立即再部署"
// 突袭 raidShip member idle ≥ no_attack_duration s (or skill ready — a passive skill that is on counts, GitHub
// #49) with no enemy in range → "保留技力立即再部署"
// next to the most advanced ground enemy it can reach: on a free tile 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
@@ -311,7 +312,13 @@ function raidPoll(battle, st) {
for (const u of st.members[ID.raid]) {
if (!onField(u) || !u.canAct) continue;
const since = Math.max(u.lastAttackAt ?? -Infinity, u.deployedAt ?? -Infinity, u.mem[KEY.raid] ?? -Infinity);
const ready = !!(u.skill && u.skill.ready && !(u.skill.active && u.skill.isTimed));
// 技能就绪: a charged skill, or a passive skill that is on (GitHub #49: skills.js `ready` is false for every passive,
// so 缄默德克萨斯 / 宴 … only ever jumped on the idle trigger; the reporter's footage of the official game shows
// 缄默德克萨斯 jumping within her passive's 10 s with no enemy in range). The engine keeps a passive on for the whole
// deployment, so such a member may jump whenever nothing is in its range [ASSUMED: "技能就绪" of a passive = the
// skill being on]; the landing rule below keeps it from hopping. Here only — the global `ready` stays as it is.
const sk = u.skill;
const ready = !!(sk && !sk.noSkill && (sk.ready || (sk.kind === 'passive' && sk.active)) && !(sk.active && sk.isTimed));
const idleOk = battle.time - since >= idle - 1e-9;
if (!(ready || idleOk)) continue;
if (battle.enemiesInKeys(u.rangeKeys || [], u, u.profile).length) continue;
+2 -1
View File
@@ -739,6 +739,7 @@ const BY_ITEM = {
},
// 骑士戒律 (卡西米尔): skill start ⇒ 20 s aura: enemies in range ASPD ×attack_speed, move ×move_speed;
// + 卡西米尔竞技旗: during the (timed) skill ATK +atk, lethal damage does not retreat it — it retreats when the skill ends
// ("受到致命伤害时不撤退,技能结束后退场": a knock-out put off, so a `dying` retreat — Touch's 超脱 counts it [ASSUMED])
chess_item_6_10_e(battle, u, rec, S) {
const p = bp(rec, 'act2autochess_equip_acarm119_global_buff');
const a = bp(rec, 'act2autochess_equip_acarm119_ability');
@@ -763,7 +764,7 @@ const BY_ITEM = {
battle.removeBuff(u, comboKey);
if (doomed && c.reason !== 'death') {
doomed = false;
battle.after(0, () => { if (u.alive) battle.retreat(u, { reason: 'retreat' }); });
battle.after(0, () => { if (u.alive) battle.retreat(u, { reason: 'retreat', dying: true }); });
}
});
S.on('fatal', (c) => {
+5
View File
@@ -236,6 +236,11 @@ Each item is a mistake this project already made once. Tick every one for every
`enemies_bosses.test.js` "沉默: exactly the abilities whose handbook line is SILENCE-flagged can be silenced".
- [ ] **10. Tests** — at least one per skill and per talent, plus the trigger rule, the range toggle, anti-air and
every module; the golden files updated in the same pull request (an intended change).
- [ ] **11. 治疗 or 生命回复速度** — an effect PRTS describes as raising the target's 「生命回复速度」 (a 备注 「增加目标的
“生命回复速度”属性,不受治疗加成和禁疗影响」; 分支特性信息 吟游者) is an hpRegen / hpRegenRatio buff on the target, never
`battle.heal`: 禁疗 and 无法被友方治疗 (`noHeal`) do not stop it and no 治疗加成 scales it (damage.js heal `regen`).
Examples: 安洁莉娜 兼职工作, the 吟游者 trait (professions.js `bardRegen`), 调香师, 瑕光 S2, 铃兰 S3, 锡人;
`test/content/feedback5-regen.test.js` (GitHub #96 / #137). A per-second 「恢复…生命」 without such a note stays a heal.
## Old references
@@ -11,6 +11,9 @@ import { num, talentBb, moduleBb, enemiesInGrid, once, spTimeBonus, makeZone, in
* for projectile_delay_time s, ground enemies within projectile_range tiles take atk_scale × ATK arts per second,
* allies there recover hp_recovery_per_sec_ratio × ATK per second. Elite: 凋敝魂灵 (skill@damage_scale: damage-over-
* time taken by ground enemies inside a unit ×1.2) and the module's +sp_recovery_per_sec SP while a unit exists.
* PRTS 锡人 技能2 备注: the unit caches her ATK at the cast, several can exist and their effects add up, and "生命恢复的
* 提供方式为增加目标的“生命回复速度”属性,不受治疗加成和禁疗影响" — an hpRegen buff per unit on the allies inside it
* (no heal: 无法被友方治疗 / 禁疗 units get it too), set at each pulse until the next.
*/
export function tinmanKit(bb, chess, def) {
const dur = num(bb.projectile_delay_time, 10);
@@ -28,6 +31,7 @@ export function tinmanKit(bb, chess, def) {
const x = tgt ? tgt.x : unit.x + unit.fwd[1], y = tgt ? tgt.y : unit.y + unit.fwd[0];
const atk = unit.s.atk;
unit.mem.tinZones = (unit.mem.tinZones ?? 0) + 1;
const regenKey = `tinman:zone:${unit.id}:${unit.mem.tinZoneSeq = (unit.mem.tinZoneSeq ?? 0) + 1}`;
makeZone(battle, unit, {
x, y, radius, duration: dur, skill: 'tinman', onPulse(b) {
for (const e of b.foesInRadius(x, y, radius)) {
@@ -35,7 +39,12 @@ export function tinmanKit(bb, chess, def) {
if (wither > 1) b.addBuff(e, { key: witherKey, duration: 1.05, data: { mul: wither }, source: unit });
b.dealDamage(unit, e, { amount: atk * dmgScale, type: 'arts', isSkill: true, canDodge: false, tags: ['dot', 'zone'] });
}
if (healRatio > 0) for (const a of b.alliesInRadius(x, y, radius, null)) if (a.hp < a.s.maxHp) b.heal(unit, a, atk * healRatio, { tags: ['zone'] });
// pulses every second: the buff bridges to the next pulse (two ticks over), the last one ends with the unit
if (healRatio > 0) {
for (const a of b.alliesInRadius(x, y, radius, null)) {
if (b.allySelectable(a, unit)) b.addBuff(a, { key: regenKey, duration: 1 + 2 * b.dt, source: unit, mods: { hpRegen: atk * healRatio } });
}
}
},
onEnd() { unit.mem.tinZones = Math.max(0, (unit.mem.tinZones ?? 1) - 1); },
});
@@ -6,7 +6,9 @@ import { num, talentBb, moduleBb, up } from '../shared/tier1.js';
export default {
// ---------------------------------------------------------------------------------------------------------------
// 2_14 调香师 精调: ASPD +attack_speed (−50), ATK +atk. 熏衣草: every ally on the field recovers
// atk_to_hp_recovery_ratio × ATK HP per second. Elite module (RIN-Y, hidden attack@max_target): heals 4 allies.
// atk_to_hp_recovery_ratio × ATK HP per second — PRTS 天赋备注 "生命恢复的提供方式为增加目标的“生命回复速度”属性(直接加算),
// 不受治疗加成和禁疗影响": an hpRegen buff, no heal, so 无法被友方治疗 (折桠, 收割者) and 禁疗 units get it too (GitHub #137).
// Elite module (RIN-Y, hidden attack@max_target): heals 4 allies.
// S1 治疗强化·β型 (alt): ATK +atk for its duration.
chess_char_2_14_a: (bb, chess) => {
const t = talentBb(chess, 0);
@@ -18,10 +20,12 @@ export default {
talents: [{ install(battle, unit) {
const r = num(t.atk_to_hp_recovery_ratio);
if (!(r > 0)) return;
battle.every(1, () => {
// one buff per 调香师 (直接加算: two add up), refreshed while she is on the field; it lapses 0.5 s after she leaves
const key = `flower:lavender:${unit.id}`;
battle.every(0.25, () => {
if (!up(unit)) return;
const amt = unit.s.atk * r;
for (const a of battle.alliesFor(unit)) if (a.hp < a.s.maxHp) battle.heal(unit, a, amt, { aura: true, tags: ['talent'] });
const v = unit.s.atk * r;
for (const a of battle.alliesFor(unit)) battle.addBuff(a, { key, duration: 0.5, source: unit, mods: { hpRegen: v }, tags: ['talent'] });
}, { owner: unit });
} }],
};
@@ -7,14 +7,18 @@ import {
giveSp,
} from '../shared/tier3.js';
/** Refresh period (s) of 瑕光 S2's 生命回复速度 buff (it lasts two periods, so it never lapses while the skill runs). */
const REGEN_IV = 0.25;
export default {
// ---- 3_12 瑕光 · 守护者 — S3 先贤化身: ATK/DEF +, bonus arts per hit, heals another nearby ally per attack;
// 剑盾骑士: hurt-SP skills of the team also gain SP on attack; 仁慈: attacks sleeping enemies (first, ×atk_scale);
// 精锐 module GUA-Y: damage taken −15 %
// S1 光芒涌动 (自动触发 ⇒ DEFAULT, charges): next attack ×atk_scale phys + heals the most injured ally of the 3×3 (herself
// included) for heal_scale × ATK; S2 慑敌辉光: ATK +, puts every ground enemy on her own tile and every enemy she
// blocks to sleep (PRTS 备注; for the skill's duration: no own value in the data) and heals every ally of the
// skill range by ATK × ratio each second;
// blocks to sleep (PRTS 备注; for the skill's duration: no own value in the data) and gives every ally of the
// skill range 生命回复速度 +ATK × ratio while it runs (PRTS 技能2 备注 "生命恢复的提供方式为基于自己的攻击力,增加目标的
// “生命回复速度”属性,不受治疗加成和禁疗影响": an hpRegen buff, no heal — GitHub #137);
// 精锐 module GUA-X: her heals on allies under hp_ratio HP × heal_scale
chess_char_3_12_a: (bb, chess, def) => {
const d = defOf(chess, def);
@@ -62,6 +66,19 @@ export default {
skchr_blemsh_2: (s) => {
const grid = copyGrid(s.rangeGrid) ?? NINE;
const ratio = num(s.bb['attack@atk_to_hp_recovery_ratio'], num(s.bb.atk_to_hp_recovery_ratio, 0));
// "周围的所有友方单位每秒恢复相当于攻击力N%的生命值": an hpRegen buff on every ally on the skill range's tiles (no
// device, no 孤立 unit), refreshed every REGEN_IV while the skill runs and removed at its end [ASSUMED: from the
// start of the skill — unlike 铃兰's, the note names no delay]
const regenKey = (unit) => `blemsh:regen:${unit.id}`;
const regen = (battle, unit) => {
if (!(ratio > 0)) return;
const keys = new Set(gridKeys(grid, unit));
const v = unit.s.atk * ratio;
for (const a of battle.allyUnits) {
if (!a.alive || !a.deployed || a.hidden || a.kind === 'device' || !onTiles(a, keys) || !battle.allySelectable(a, unit)) continue;
battle.addBuff(a, { key: regenKey(unit), duration: REGEN_IV * 2, source: unit, mods: { hpRegen: v } });
}
};
return {
kind: 'duration',
heal: false,
@@ -78,14 +95,16 @@ export default {
}
fx(battle, 'aoe', unit, { radius: 0.5, skill: 'blemsh_2', status: 'sleep', n });
unit.mem.blemshRegen = 0;
regen(battle, unit);
},
onTick({ battle, unit, dt }) { // "周围的所有友方单位每秒恢复相当于攻击力N%的生命值"
if (!(ratio > 0)) return;
onTick({ battle, unit, dt }) {
unit.mem.blemshRegen = (unit.mem.blemshRegen ?? 0) + dt;
while (unit.mem.blemshRegen >= 1 - 1e-9) {
unit.mem.blemshRegen -= 1;
for (const a of battle.injuredAlliesInKeys(new Set(gridKeys(grid, unit)), unit)) battle.heal(unit, a, unit.s.atk * ratio);
}
if (unit.mem.blemshRegen < REGEN_IV - 1e-9) return;
unit.mem.blemshRegen = 0;
regen(battle, unit);
},
onEnd({ battle, unit }) {
for (const a of battle.allyUnits) if (a.findBuff(regenKey(unit))) battle.removeBuff(a, regenKey(unit));
},
};
},
@@ -92,7 +92,7 @@ export default withDefaults({
onEnd({ unit }) { if (unit.mem.bardBase != null) unit.profile.auraRatio = unit.mem.bardBase; },
},
talents: [
{ install(battle, unit) { // 过往尘埃: 3 motes; touching an operator ⇒ her trait heal ×1.5 on it for 6 s; mote back after 6 s
{ install(battle, unit) { // 过往尘埃: 3 motes; touching an operator ⇒ her trait regen ×1.5 on it for 6 s; mote back after 6 s
unit.mem.motes = new Array(baseCnt).fill(-Infinity);
unit.mem.noInspire = true; // trait: 自身不受鼓舞影响 (another bard's 鼓舞 skips her)
const cooldown = () => (S1 && skillActive(unit) ? num(bb.talent_cool_down, 3) : num(t0.cooldown, 6)); // S1: 重生速度加快
@@ -126,8 +126,9 @@ export default withDefaults({
battle.fx('mote', { x: a.x, y: a.y, id: a.id });
}
});
battle.on('heal', (c) => {
if (c.source === unit && c.opts?.aura && c.target.findBuff(`cetsyr:mote:${unit.id}`)) c.amount *= num(t0['attack@trait_mul'], 1.5);
// "受到魔王特性效果提升至1.5倍": her trait's 生命回复速度 on that operator (professions.js bardRegen hook)
battle.on('bardRegen', (c) => {
if (c.unit === unit && c.target.findBuff(`cetsyr:mote:${unit.id}`)) c.value *= num(t0['attack@trait_mul'], 1.5);
}, { owner: unit });
} },
{ install(battle, unit) { // 魔王残响: every ally takes −10 % damage from 萨卡兹 enemies (while she is in the squad)
@@ -46,7 +46,7 @@ export default {
c.amount = 0;
}, { owner: unit, priority: 100 });
battle.on('heal', (c) => { // merged into the same heal
if (c.source !== unit || !unit.mem.bldskBonus || c.target !== unit.mem.bldskBonus) return;
if (c.source !== unit || c.opts?.regen || !unit.mem.bldskBonus || c.target !== unit.mem.bldskBonus) return; // (not her own 生命回复速度 tick)
unit.mem.bldskBonus = null;
// the bonus is part of the same heal: the healer's and the target's healing multipliers apply to it too
c.amount += c.target.s.maxHp * ratio * num(unit.s.healingDealtMul, 1) * num(c.target.s.healingTakenMul, 1);
@@ -66,7 +66,8 @@ export default {
// noHeal (no heal pick, no heal from others) + healFree (her own heals too; S3's start heal "无视禁疗"), shown as
// the status 'healFree' until she leaves. "强制退出战场视为撤回干员": a retreat (Battle.retreat drops the buff) — she
// lies down where she stood and redeploys there, like every operator that leaves the field (PRTS 卫戍协议/帮助
// "干员退场后…原地留下一个“倒地干员”…自动部署至该位置"; Battle.isDown, GitHub #60).
// "干员退场后…原地留下一个“倒地干员”…自动部署至该位置"; Battle.isDown, GitHub #60). With her death animation
// (`dying`): PRTS Touch(卫戍协议) 超脱 备注 counts it as a knock-out ("如史尔特尔的天赋效果").
const wait = num(t1['surtr_t_2[withdraw].interval'], 8);
battle.on('deploy', (c) => { if (c.unit === unit) unit.mem.ember = false; }, { owner: unit });
battle.on('fatal', (c) => {
@@ -77,7 +78,7 @@ export default {
const dep = unit.deploySeq;
battle.addBuff(unit, { key: 'surtr:ember', status: 'healFree', flags: { noHeal: true, healFree: true } });
battle.fx('ember', { x: unit.x, y: unit.y, id: unit.id });
battle.after(wait, () => { if (unit.alive && unit.deploySeq === dep) battle.retreat(unit, { reason: 'retreat' }); }, { owner: unit });
battle.after(wait, () => { if (unit.alive && unit.deploySeq === dep) battle.retreat(unit, { reason: 'retreat', dying: true }); }, { owner: unit });
}, { owner: unit, priority: -60 });
} },
],
@@ -10,9 +10,10 @@ const MOTE_HIT_RADIUS = 0.4;
export default {
// ---------------------------------------------------------------------------------------------------------------
// 魔王 — bard (aura heal 10 % ATK/s). S3 编织重构现世 (30 s): skill range, aura 65 %, motes never vanish, other allies in
// range get 鼓舞 = +65 % of her max HP, HP of everyone in range is equalised every 2 s.
// T1 过往尘埃: 3 motes orbit her; one colliding with an operator vanishes and gives it ×1.5 aura healing for 6 s, then
// 魔王 — bard (trait: 生命回复速度 +10 % ATK on the allies in range, professions.js bardRegen). S3 编织重构现世 (30 s):
// skill range, trait 65 %, motes never vanish, other allies in range get 鼓舞 = +65 % of her max HP, HP of everyone in
// range is equalised every 2 s.
// T1 过往尘埃: 3 motes orbit her; one colliding with an operator vanishes and gives it ×1.5 of her trait for 6 s, then
// respawns after 6 s.
// T2 魔王残响: allies take −10 % damage from Sarkaz enemies. Module (elite): ≥2 other ops in range → ATK +8 %.
chess_char_5_09_a: (bb, chess, def) => {
@@ -94,10 +95,11 @@ export default {
battle.fx('mote', { x: hit.x, y: hit.y, id: hit.id });
}
});
battle.on('heal', (c) => {
if (c.source !== unit || !c.opts?.aura) return;
// "受到魔王特性效果提升至1.5倍": his trait's 生命回复速度 on that operator (professions.js bardRegen hook)
battle.on('bardRegen', (c) => {
if (c.unit !== unit) return;
const b = c.target.findBuff('cetsyr:mote');
if (b) c.amount *= num(b.data.mul, 1);
if (b) c.value *= num(b.data.mul, 1);
}, { owner: unit });
} },
{ install(battle, unit) { // 魔王残响
@@ -5,8 +5,11 @@ import { AURA_IV, AURA_DUR, num, talent, skillGrid, mods, isOp, lazySkills, whil
export default {
// ---------------------------------------------------------------------------------------------------------------
// 铃兰 — S3 狐火渺然 (27/29 s): no attacks, skill range, every enemy in range is sluggish, allies in range heal 9/11 %
// ATK per second, T2 ×scale_delta_to_one. T1 技力光环·辅助: Supporters +0.4 SP/s (highest wins).
// 铃兰 — S3 狐火渺然 (27/29 s): no attacks, skill range, every enemy in range is sluggish, allies in range recover 9/11 %
// ATK per second, T2 ×scale_delta_to_one. PRTS 技能3 备注: "生命恢复的提供方式为基于铃兰的攻击力增加目标的“生命回复速度”
// 属性,不受治疗加成和禁疗影响" and "技能开启第一秒内提供生命回复为0,生命回复速度数额每秒刷新一次" — an hpRegen buff (no heal:
// 无法被友方治疗 / 禁疗 units get it too), set at each full second of the skill on the allies then in range, none in the
// first second, removed when the skill ends. T1 技力光环·辅助: Supporters +0.4 SP/s (highest wins).
// T2 画地为牢: sluggish enemies in range also take +20 % damage for the same time. Module (elite): +0.2 SP/s with an
// enemy in range.
chess_char_5_10_a: (bb, chess, def) => {
@@ -14,6 +17,7 @@ export default {
const boost = num(bb.scale_delta_to_one, 1);
const healRatio = num(bb['attack@atk_to_hp_recovery_ratio']);
const fragile = num(t1.damage_scale, 1) - 1;
const foxKey = (unit) => `lisa:fox:${unit.id}`;
return {
// S1 全力以赴 (duration): ATK +, ASPD +. S2 儿时的舞乐 (toggle, 持续时间无限): ATK +, 2 targets.
skills: lazySkills({
@@ -35,9 +39,14 @@ export default {
if (unit.mem.foxHeal >= 1) {
unit.mem.foxHeal -= 1;
if (!(healRatio > 0)) return;
for (const a of battle.alliesInGrid(unit)) if (a.hp < a.s.maxHp) battle.heal(unit, a, unit.s.atk * healRatio, { aura: true });
// until the next refresh (a little longer, so it never lapses in between; onEnd takes it off)
const v = unit.s.atk * healRatio;
for (const a of battle.alliesInGrid(unit)) battle.addBuff(a, { key: foxKey(unit), duration: 1.25, source: unit, mods: { hpRegen: v } });
}
},
onEnd({ battle, unit }) {
for (const a of battle.allyUnits) if (a.findBuff(foxKey(unit))) battle.removeBuff(a, foxKey(unit));
},
},
talents: [
{ install(battle, unit) { spAura(battle, unit, num(t0.sp_recovery_per_sec), (a) => isOp(a) && a.def?.profession === 'SUPPORT'); } },
@@ -3,6 +3,7 @@
import { aggregateMods } from '../../../buffs.js';
import { COLS } from '../../../constants.js';
import { bardRegen } from '../../../professions.js';
import {
num, bv, tbb, tdesc, moduleBb, parseN, live, enemiesIn, isTok, onDefaultSkill, selectedSkill, aura,
} from '../shared/tier6.js';
@@ -37,7 +38,8 @@ function skadi2(bb, chess, def) {
const isDef = onDefaultSkill(chess), sid = selectedSkill(chess, def);
const tokId = def?.talents?.[0]?.tokenKey || (chess?.tokens || [])[0] || 'token_10017_skadi2_dedant';
const auraRatio = num(tb['attack@atk_to_hp_recovery_ratio'], 0.1);
// S1 / S2 raise the trait heal ("特性效果提高至N%") while they run; S3 (default) turns it into the tide
// S1 / S2 raise the trait ("特性效果提高至N%") while they run; S3 (default) turns it into the tide. The trait is a
// 生命回复速度 buff on the allies, not a heal (PRTS 分支特性信息 吟游者; professions.js bardRegen)
const skillRatio = num(bb['attack@atk_to_hp_recovery_ratio'], auraRatio);
const seaborns = (battle, unit) => battle.allyUnits.filter((t) => isTok(t, tokId, unit) && live(t));
const covered = (battle, unit, toks) => { // allies inside her range ∪ the seaborns' ranges
@@ -52,7 +54,7 @@ function skadi2(bb, chess, def) {
return seaborns(battle, unit).some((t) => t.rangeKeySet?.has(k));
};
const skills = {
// S1 同归殊途之吟 (SP_FULL): full self heal, max HP +max_hp, trait heal attack@atk_to_hp_recovery_ratio, and
// S1 同归殊途之吟 (SP_FULL): full self heal, max HP +max_hp, trait attack@atk_to_hp_recovery_ratio, and
// damage_resistance of the damage taken by every ally of her (+ 海嗣) range is transferred to her (install)
skchr_skadi2_1: {
kind: 'duration',
@@ -60,7 +62,7 @@ function skadi2(bb, chess, def) {
onStart({ battle, unit }) { unit.hp = unit.s.maxHp; battle.fx('heal', { x: unit.x, y: unit.y, id: unit.id }); },
},
// S2 同葬无光之愿 (toggle): 鼓舞 ATK / DEF = atk / def × her ATK / DEF on every other ally of her (+ 海嗣) range,
// trait heal attack@atk_to_hp_recovery_ratio (trait pulse). 自动触发 with effects on her allies only (nothing to target):
// trait attack@atk_to_hp_recovery_ratio (trait pulse). 自动触发 with effects on her allies only (nothing to target):
// on as soon as it is ready (SP_FULL, like 魔王 S1 往昔萦绕身旁); until 0.2.0 the data's DEFAULT left it off until an
// enemy came into her (or a 海嗣's) range.
skchr_skadi2_2: { kind: 'toggle', trigger: 'SP_FULL' },
@@ -72,7 +74,7 @@ function skadi2(bb, chess, def) {
onStart({ battle, unit }) { battle.fx('tide', { x: unit.x, y: unit.y, id: unit.id }); },
},
trait: {
install(battle, unit) { // replaces the bard aura: heal normally, tide (true damage + 鼓舞 + self drain) during S3
install(battle, unit) { // replaces the bard aura: 生命回复速度 normally, tide (true damage + 鼓舞 + self drain) during S3
unit.mem.noInspire = true; // 自身不受鼓舞影响
const isInspire = (b) => b.key === 'inspire' || b.status === 'inspire' || b.key.startsWith('inspire:') || b.key.endsWith(':inspire');
// "海嗣的攻击范围视为自身攻击范围的延伸": an enemy in a 海嗣's range also satisfies her DEFAULT trigger
@@ -103,10 +105,9 @@ function skadi2(bb, chess, def) {
const va = unit.s.atk * num(bb.atk), vd = unit.s.def * num(bb.def);
for (const a of allies) if (a !== unit) { inspire(battle, a, va, unit); inspire(battle, a, vd, unit, 'def'); }
}
if (n % 2 === 0) {
const amount = unit.s.atk * (on ? skillRatio : num(unit.profile?.auraRatio, auraRatio));
for (const a of allies) if (a.hp < a.s.maxHp) battle.heal(unit, a, amount, { aura: true });
}
// the trait over her range ∪ the 海嗣' ranges, refreshed every pulse (it lapses 0.75 s after the last one)
const v = unit.s.atk * (on ? skillRatio : num(unit.profile?.auraRatio, auraRatio));
for (const a of allies) bardRegen(battle, unit, a, v, 0.75);
}, { owner: unit });
},
},
@@ -93,7 +93,7 @@ function lumen(bb, chess, def) {
const res = -num(t0.one_minus_status_resistance, -0.5), thr = num(t0.hp_ratio, 0.75);
battle.on('heal', (ctx) => {
const t = ctx.target;
if (ctx.source !== unit || !t || !(res > 0) || !(base > 0)) return;
if (ctx.source !== unit || ctx.opts?.regen || !t || !(res > 0) || !(base > 0)) return; // "治疗的目标": not her own 生命回复速度 tick
const after = Math.min(t.s.maxHp, t.hp + ctx.amount);
battle.applyStatus(t, 'resist', { duration: after / t.s.maxHp > thr ? special : base, value: Math.min(1, res), source: unit });
}, { owner: unit, priority: -10 });
@@ -19,16 +19,16 @@ export default {
// `attack@max_target` targets, every 医疗 operator of hers ATK +`attack@atk` herself included [ASSUMED: her own
// player's operators, as 余's "全场所有干员"; summons not].
// S3 恳切福音 (40 s): content/tokens.js touchGospel — the one implementation the 外勤医疗 strategy's Touch runs too
// (5-2 grid, ATK +atk, 2 targets, an extra heal of 30 % of the main one on the target or an orthogonal neighbour,
// ×heal_scale on allies at ≤ hp_ratio HP).
// (5-2 grid, ATK +atk, 2 targets, ×heal_scale on allies below hp_ratio HP, and an extra heal of 30 % of the main
// heal's base on the main target or an orthogonal neighbour — the lowest HP ratio, a full-HP one included — which
// takes the ×heal_scale of its own recipient: PRTS 技能3 备注).
// Talents 攫升 / 超脱: content/tokens.js mapCharTalents (the strategy's Touch too); the module's 超脱 upgrade (8 SP at
// module Lv3) comes with the record's talents.
// Module PHY-X (elite, trait addition): "治疗生命值低于50%的友方单位时治疗量提升15%" — every heal of hers on an ally
// below `hp_ratio` HP (strictly: "低于") ×`heal_scale` (the trait blackboard). With S3's ×1.35 / ×1.40 it
// multiplies (×1.61 at Lv7): both are `heal_scale` blackboards, the 治疗倍率, and PRTS 游戏数据基础 §倍率 says "同种
// 倍率间叠乘" — no Touch-specific note or buff template exists. It runs before S3's hook, so S3's 30 % extra heal is
// a share of the main heal with both bonuses and, like S3's ×1.35 / ×1.40 in touchGospel, never multiplies that
// share again [ASSUMED].
// 倍率间叠乘" — no Touch-specific note or buff template exists. S3's extra heal is a heal of hers like any other: its
// recipient below `hp_ratio` gets the ×1.15 too (its base is taken before either bonus).
// Triggers (data, nothing set here): S1 DEFAULT (an injured ally in her range); S2 / S3 ACTIVE_RANGE — the owner's
// rule of 2026-10-05 read for a heal skill: an injured ally inside the running 3-10 / 5-2 range casts.
char_613_acmedc: (bb, chess, def) => {
@@ -79,8 +79,7 @@ export default {
install(battle, unit) {
if (phyScale !== 1 && phyRatio > 0) {
battle.on('heal', (ctx) => {
// (S3's extra heal is a share of the main heal, which already carries it: touchGospel's `touchExtra`)
if (ctx.source !== unit || !ctx.target || ctx.opts?.regen || unit.mem.touchExtra) return;
if (ctx.source !== unit || !ctx.target || ctx.opts?.regen) return;
if (ctx.target.hpRatio < phyRatio - 1e-9) ctx.amount *= phyScale;
}, { owner: unit, priority: 10 });
}
+48 -24
View File
@@ -11,7 +11,8 @@
// 沙之碑 on appear: owner ATK × atk_scale arts + stun (skill range 3×3), blocks 3 (no attack), talent duration 20 s
// 战术装备 on appear: stun around (bb.stun), blocked enemies DEF + talent def (−160), talent duration 25 s
// “小自在” arts melee blocker, talent duration 25 s; kills emit `summonKill` (夕's 化境 is the 夕 kit's job)
// 斯卡蒂的海嗣 untargetable range extension of 浊心斯卡蒂: heals allies in its range (owner ATK × trait ratio /s);
// 斯卡蒂的海嗣 untargetable range extension of 浊心斯卡蒂: her trait's 生命回复速度 on the allies in its range (owner
// ATK × trait ratio /s);
// while the owner's skill runs: owner ATK × atk_scale true dmg/s to enemies + 鼓舞 owner ATK × bb.atk;
// talent duration 25/30 s, then redeploys after respawnTime (30/25 s, DP cost from data)
// “耀阳” on appear: owner ATK × atk_scale true + stun in the skill grid (+1 hit if the previously deployed
@@ -85,6 +86,7 @@ import { absoluteRangeKeys, sortEnemyTargets, canTargetEnemy } from '../targetin
import { bodyInKeys, bodyOnTile } from '../body.js';
import { hasHp } from '../damage.js';
import { genericKit } from './generic.js';
import { bardRegen } from '../professions.js';
import { normDir, localOrder } from '../dir.js';
import { SKILL_SUMMON_START_DEPLOY } from '../../../shared/constants.js';
@@ -535,7 +537,11 @@ function duskDragon(bb, raw, def) {
};
}
/** 斯卡蒂的海嗣 (浊心斯卡蒂 talent 远古血亲): range extension of its owner (heal aura / S3 damage + 鼓舞). */
/**
* 斯卡蒂的海嗣 (浊心斯卡蒂 talent 远古血亲): range extension of its owner (her trait's 生命回复速度 — professions.js bardRegen,
* keyed by the owner: one trait effect per ally — / S3 damage + 鼓舞). Only while the owner fights with the generic kit:
* her own kit (kits/ops/chess_char_6_04-skadi2.js) covers the 海嗣' ranges itself.
*/
function seaborn(bb, raw, def) {
const life = num(talentBb(def, 'duration').duration, 0);
const healRatio = num(def?.traitBb?.['attack@atk_to_hp_recovery_ratio'], 0);
@@ -567,9 +573,9 @@ function seaborn(bb, raw, def) {
} else if (healRatio > 0) {
const ownerKeys = o && o.alive && o.deployed ? (o.rangeKeySet || new Set(o.rangeKeys || [])) : null;
for (const a of battle.alliesInGrid(unit)) {
if (a === unit || a.hp >= a.s.maxHp - 1e-6) continue;
if (ownerKeys && ownerKeys.has(a.tileR * COLS + a.tileC)) continue; // the owner's own aura already heals it
battle.heal(unit, a, atk * healRatio);
if (a === unit) continue;
if (ownerKeys && ownerKeys.has(a.tileR * COLS + a.tileC)) continue; // the owner's own trait already covers it
bardRegen(battle, o ?? unit, a, atk * healRatio, 1.25); // refreshed every second
}
}
}, { owner: unit });
@@ -1338,12 +1344,26 @@ export function spawnYanyou(battle, playerId, { atk, hp, atkMul = 1, dmgTakenMul
// ---------------------------------------------------------------------------------------------------------------
// band map characters (预备干员-医疗 / Touch)
/**
* Exits that give Touch's 超脱 its SP (PRTS Touch(卫戍协议) 第二天赋 备注 "部分有死亡动画的强制撤退(如史尔特尔的天赋效果)也能触发这一
* 天赋"): a knock-out ('killed') and a forced exit that plays the death animation — Battle.retreat `dying`, a knock-out put
* off by the operator's own effect: 史尔特尔's 余烬 (the PRTS example) and 骑士戒律 + 竞技旗 ("受到致命伤害时不撤退,技能结束后
* 退场" [ASSUMED: the same kind of exit]). Not the exits a skill plans — 耀骑士临光 S2's "技能结束后自动撤退", 伊内丝 S3's "放置
* 一个影哨后离场" — nor the 商人's "不足时自动撤退" ('merchant'), the 突袭 jump ('raid'), the 联防 setup (FORCED_EXIT) or a
* summon's end ('expired') [ASSUMED: plain 撤退 without a death animation]. A battle runs on its own — the player has no
* 撤退 command in it — so none of these is a player's own retreat.
*/
const touchExitCounts = (ctx) => ctx.reason === 'killed' || (ctx.reason === 'retreat' && !!ctx.dying);
/**
* Talents of the band map characters (data talents of the character record) — and of the Touch 补位 stand-in, whose kit
* (kits/ops/standin-acmedc.js) uses this one implementation, the module's 超脱 upgrade (8 SP) coming with the record:
* plain stat talent "攻击力+4%" (预备干员-医疗 攻击提升) → persistent ATK/DEF/HP/ASPD buff
* 攫升 "治疗目标时使其获得3点技力" (Touch) → every heal by the character gives the healed unit `sp` SP
* 超脱 "攻击范围内的友方干员被击倒时获得5点技力" (Touch) → an allied operator knocked out on a tile of its range: +`sp` SP
* 攫升 "治疗目标时使其获得3点技力" (Touch) → every heal the character outputs gives its target `sp` SP — PRTS 备注 "本天赋只需
* Touch输出治疗便能触发(无需实际产生治疗量)": herself too, and a heal that restores nothing (a full-HP target: S3's
* extra heal); not a device or a unit without a skill, not her own HP-regeneration tick (no heal she outputs)
* 超脱 "攻击范围内的友方干员被击倒时获得5点技力" (Touch) → an allied operator knocked out (or forced out dying:
* touchExitCounts) on a tile of its range: +`sp` SP
*/
export function mapCharTalents(def) {
const out = [];
@@ -1355,7 +1375,7 @@ export function mapCharTalents(def) {
out.push({ install(battle, unit) {
battle.on('heal', (ctx) => {
const tg = ctx.target;
if (ctx.source !== unit || !tg || tg === unit || tg.kind === 'device' || !tg.skill || !(ctx.amount > 0)) return;
if (ctx.source !== unit || ctx.opts?.regen || !tg || tg.kind === 'device' || !tg.skill || tg.skill.noSkill) return;
tg.skill.gainSp(sp, 'talent');
}, { owner: unit, priority: -200 });
} });
@@ -1363,7 +1383,7 @@ export function mapCharTalents(def) {
out.push({ install(battle, unit) {
battle.on('death', (ctx) => {
const d = ctx.unit;
if (ctx.reason !== 'killed' || !unit.alive || !unit.deployed || !unit.skill || !d || d === unit || d.kind !== 'op' || d.ownerId !== unit.ownerId) return;
if (!touchExitCounts(ctx) || !unit.alive || !unit.deployed || !unit.skill || !d || d === unit || d.kind !== 'op' || d.ownerId !== unit.ownerId) return;
if ((unit.rangeKeySet || new Set(unit.rangeKeys || [])).has(d.tileR * COLS + d.tileC)) {
unit.skill.gainSp(sp, 'talent');
battle.fx('spGain', { x: unit.x, y: unit.y, id: unit.id, n: sp });
@@ -1391,11 +1411,19 @@ function reserveMedicKit(bb, raw, def) {
}
/**
* Touch 恳切福音 (skchr_acmedc_3): +ATK, 2 heal targets in the skill range, ×heal_scale on allies ≤ hp_ratio, +addition
* Touch 恳切福音 (skchr_acmedc_3): +ATK, 2 heal targets in the skill range, ×heal_scale on allies below hp_ratio, +addition
* heal — one implementation for the 外勤医疗 map character (touchKit) and the Touch 补位 stand-in (kits/ops/
* standin-acmedc.js). `skill` = the skill record (`rangeGrid`, `duration`) of blackboard `bb`. Returns `{ skill:
* SkillSpec, install(battle, unit) }`: `install` adds the heal boost, which acts while the unit's skill runs — install it
* on a unit whose skill is this one only.
* on a unit whose skill is this one only. PRTS Touch(卫戍协议) 技能3 and its 备注:
* - "对生命值低于一半的友方单位治疗量提高为原来的130%": strictly below hp_ratio (PRTS 修正: 低于, not the old 不高于);
* - "并额外治疗一次目标或目标相邻1个友方单位,治疗量为主目标的30%": once per heal action, at the main (first = most
* injured) target's hit; 30 % of that heal's base (ATK × its scales, before the ×heal_scale the main target may get);
* - 备注 "额外治疗范围 x-5…优先选择生命比例更低的单位治疗(可治疗生命值已满单位)": the main target or one of its 4
* orthogonal neighbours, the lowest HP ratio first, a full-HP one included [ASSUMED: on equal ratios the main target,
* then the battle's ally order]; never a 禁疗 / 孤立 / 无法被友方治疗 unit (no heal can pick it);
* - 备注 "额外治疗可触发技能后半段的治疗量提高效果": the extra heal is a heal of its own, so its recipient gets the ×heal_scale
* when it is below hp_ratio (and the stand-in's PHY-X ×1.15), and its target gets 攫升's SP.
*/
export function touchGospel(bb, skill) {
const hpRatio = num(bb.hp_ratio, 0), boost = num(bb.heal_scale, 1), extra = num(bb['attack@addition_heal_scale'], 0);
@@ -1409,28 +1437,24 @@ export function touchGospel(bb, skill) {
targeting,
onHit({ battle, unit, target, heal }) {
if (!(extra > 0) || !target || !(heal > 0)) return;
// "每次治疗2个目标,并额外治疗一次…治疗量为主目标的30%": one extra heal per heal action, for the main
// (first = most injured) target — onHit runs once per healed target
// onHit runs once per healed target: the extra heal comes with the first (main) one of the action
const n = unit.stats.attacks;
if (unit.mem.touchExtraAt === n) return;
unit.mem.touchExtraAt = n;
let best = target.hp < target.s.maxHp - 1e-6 ? target : null;
for (const a of battle.alliesInRadius(target.x, target.y, 1, unit.ownerId)) {
if (a === target || a.hp >= a.s.maxHp - 1e-6 || a.s.flags.noHeal || a.profile?.noHeal) continue; // (禁疗 / 孤立)
let best = target;
for (const a of battle.alliesInRadius(target.x, target.y, 1)) {
if (a === target || !battle.allySelectable(a, unit) || a.s.flags.noHeal || a.profile?.noHeal) continue;
if (Math.abs(a.tileR - target.tileR) + Math.abs(a.tileC - target.tileC) !== 1) continue;
if (!best || a.hpRatio < best.hpRatio) best = a;
if (a.hpRatio < best.hpRatio - 1e-9) best = a;
}
// 30 % of the main target's heal as it was applied (×heal_scale when that target was at ≤ hp_ratio)
const main = unit.mem.touchMainHeal && unit.mem.touchMainHeal.target === target ? unit.mem.touchMainHeal.amount : heal;
unit.mem.touchExtra = true; // the extra heal is a share of the main heal: no second ×heal_scale
try { battle.heal(unit, best ?? target, main * extra); } finally { unit.mem.touchExtra = false; }
// `heal` = the main heal's base (ai.js doHeal: ATK × scales, before the heal pipeline and the ×heal_scale)
battle.heal(unit, best, heal * extra);
},
},
install(battle, unit) {
battle.on('heal', (ctx) => {
if (ctx.source !== unit || !unit.skill?.active || unit.mem.touchExtra) return;
if (boost !== 1 && hpRatio > 0 && ctx.target.hpRatio <= hpRatio + 1e-9) ctx.amount *= boost;
unit.mem.touchMainHeal = { target: ctx.target, amount: ctx.amount };
if (ctx.source !== unit || ctx.opts?.regen || !unit.skill?.active) return;
if (boost !== 1 && hpRatio > 0 && ctx.target.hpRatio < hpRatio - 1e-9) ctx.amount *= boost;
}, { owner: unit });
},
};
+8 -3
View File
@@ -509,18 +509,23 @@ export function reduceElement(target, amount, el = null) {
* PRTS 异常效果 HEAL_FREE "受到的治疗量变为0") stops the unit's own too — except an HP-regeneration attribute (`regen`:
* "增减生命回复速度或生命回复速度(百分比)属性的效果不会被识别为治疗类能力") and a heal that ignores it (`ignoreHealFree`:
* 史尔特尔 S3's start heal, PRTS "无视禁疗").
* A `regen` tick (Battle status: the unit's own 生命回复速度, `s.hpRegen` — 吟游者 / 调香师 / 瑕光 S2 / 铃兰 S3 / 锡人 add to it
* with an hpRegen buff, PRTS 备注 "不受治疗加成和禁疗影响") is no 治疗: no 治疗加成 scales it — neither the healing
* multipliers nor a `heal` handler (handlers still see it, with `opts.regen`; a change they make to its amount is
* ignored).
*/
export function heal(battle, source, target, amount, opts = {}) {
if (!target || !target.alive || target.removed || !target.deployed || target.bossPool) return 0;
const self = source === target || !!opts.self;
if (!self && (target.s.flags.noHeal || (target.profile && target.profile.noHeal))) return 0;
if (target.s.flags.healFree && !opts.regen && !opts.ignoreHealFree) return 0;
let amt = amount * (source && source.s ? source.s.healingDealtMul : 1) * target.s.healingTakenMul;
const regen = !!opts.regen;
if (target.s.flags.healFree && !regen && !opts.ignoreHealFree) return 0;
let amt = regen ? amount : amount * (source && source.s ? source.s.healingDealtMul : 1) * target.s.healingTakenMul;
if (!(amt > 0) || !Number.isFinite(amt)) return 0;
if (battle._hooks.heal) {
const ctx = { source, target, amount: amt, opts };
battle.emit('heal', ctx);
amt = Number.isFinite(ctx.amount) ? Math.max(0, ctx.amount) : 0;
if (!regen) amt = Number.isFinite(ctx.amount) ? Math.max(0, ctx.amount) : 0;
// a handler may have killed / retreated the target: healing a dead unit would leave it "dead with hp > 0"
if (!target.alive || !target.deployed) return 0;
}
+23 -5
View File
@@ -371,13 +371,31 @@ const installMystic = (battle, unit) => {
}, { owner: unit });
};
/** Refresh period / lifetime (s) of a bard trait's 生命回复速度 buff: it lapses within BARD_REGEN_DUR once the bard stops. */
export const BARD_REGEN_IV = 0.25;
export const BARD_REGEN_DUR = 0.5;
/**
* 吟游者 trait "不攻击,持续恢复范围内所有友军生命(每秒相当于自身攻击力10%的生命)": PRTS 分支特性信息 吟游者 "特性为基于自身攻击力
* 来增加受益者的“生命回复速度”属性" — an hpRegen buff of `value` (the bard's ATK × ratio) on `ally`, one per bard (two bards
* add up), which the caller refreshes before it lapses (`duration`, default BARD_REGEN_DUR). No heal: 禁疗 and 无法被友方
* 治疗 (收割者 / 不屈者 / 武者 noHeal) do not stop it — PRTS 异常效果 禁疗 "增减生命回复速度…的效果不会被识别为治疗类能力"; the
* regeneration tick is the ally's own (damage.js heal `regen`, no 治疗加成). The `bardRegen` hook { unit (the bard),
* target, value } may scale one ally's share (魔王's 微尘: "使该干员受到魔王特性效果提升至1.5倍"). Also the 海嗣 range of
* 浊心斯卡蒂 (content/tokens.js, kits/ops/chess_char_6_04-skadi2.js).
*/
export function bardRegen(battle, bard, ally, value, duration = BARD_REGEN_DUR) {
if (!bard || !ally || !ally.alive || !(value > 0)) return;
let v = value;
if (battle.hasHook('bardRegen')) v = num(battle.emit('bardRegen', { unit: bard, target: ally, value: v }).value, 0);
if (v > 0) battle.addBuff(ally, { key: `trait:bard:${bard.id}`, duration, source: bard, mods: { hpRegen: v } });
}
const installBard = (battle, unit) => {
battle.every(1, () => {
battle.every(BARD_REGEN_IV, () => {
if (!unit.canAct) return;
const amount = unit.s.atk * (unit.profile.auraRatio ?? 0.1);
for (const ally of battle.alliesInGrid(unit)) {
if (ally.hp < ally.s.maxHp) battle.heal(unit, ally, amount, { aura: true });
}
const v = unit.s.atk * (unit.profile.auraRatio ?? 0.1);
for (const ally of battle.alliesInGrid(unit)) bardRegen(battle, unit, ally, v);
}, { owner: unit });
};
+49
View File
@@ -412,6 +412,55 @@ test('突袭 #51: the most advanced enemy out of reach → the jump goes to the
checkInvariants(h.b);
});
// GitHub #49: skills.js `ready` is false for every passive skill, so a passive 突袭 member (缄默德克萨斯, 宴 …) only jumped on
// the 10 s idle trigger; the reporter's footage of the official game shows 缄默德克萨斯 jumping within her passive's 10 s.
// raidPoll (only there) counts a passive skill that is on as 技能就绪; the landing rule (#51) still keeps it from hopping.
test('突袭 #49: a passive skill that is on counts as 技能就绪 — 缄默德克萨斯 jumps within a few seconds, then stays while her enemy is in range', () => {
const tex = 'chess_char_4_16_a';
const h = makeBattle({
defs: { enemies: DUMMY }, bonds: { raidShip: bond(1, 10) }, enemies: [{ key: 'enemy_addon_dummy', pos: [9, 8] }],
units: [{ chessId: tex, row: 12, col: 3 }], hooks: ['deploy', 'death'], autoFinish: false, timeLimit: 60,
});
h.step();
const u = h.unit(tex), e = h.enemy('enemy_addon_dummy');
assert.deepEqual([u.skill.kind, u.skill.ready, u.skill.active], ['passive', false, true], 'her passive: on, and the global `ready` unchanged');
assert.ok(!inRange(u, e), 'nothing in her range');
assert.ok(h.runUntil(() => raidJumps(h).length > 0, 3), 'jumped within 3 s (no 10 s idle wait)');
assert.ok(h.b.time < bondBb('raidShip').no_attack_duration - 5, `at ${h.b.time.toFixed(2)} s`);
assert.ok(inRange(u, e), `landed (${u.tileR},${u.tileC}) with the enemy in range`);
h.run(8);
assert.equal(raidJumps(h).length, 1, 'busy there: no further jump (no hopping)');
checkInvariants(h.b);
});
test('突袭 #49: non-passive members unchanged — a charged skill jumps at once, an uncharged one waits for the idle time; a passive one jumps at once', () => {
const idle = bondBb('raidShip').no_attack_duration;
const defs = {
chess: {
r_s: chessRec({ id: 'r_s', bonds: ['raidShip'], skill: { spCost: 10, initSp: 10 } }),
r_u: chessRec({ id: 'r_u', bonds: ['raidShip'], skill: { spCost: 100, initSp: 0, spType: 'INCREASE_WHEN_ATTACK' } }),
r_p: chessRec({ id: 'r_p', bonds: ['raidShip'], skill: { skillType: 'PASSIVE', spCost: 0, duration: -1, spType: 8 } }),
},
enemies: DUMMY,
};
const h = makeBattle({
defs, bonds: { raidShip: bond(1, 10, 3) }, enemies: [{ key: 'enemy_addon_dummy', pos: [9, 8] }, { key: 'enemy_addon_dummy', pos: [12, 9] }],
units: [{ chessId: 'r_s', row: 12, col: 3 }, { chessId: 'r_u', row: 11, col: 3 }, { chessId: 'r_p', row: 10, col: 3 }], hooks: ['deploy', 'death'],
autoFinish: false, timeLimit: 60,
});
h.step();
const s = h.unit('r_s'), un = h.unit('r_u'), p = h.unit('r_p');
assert.deepEqual([s.skill.ready, un.skill.ready, p.skill.kind, p.skill.ready], [true, false, 'passive', false]);
h.run(1);
const jumped = (u) => raidJumps(h).filter((c) => c.unit === u);
assert.equal(jumped(s).length, 1, 'charged: at once');
assert.equal(jumped(p).length, 1, 'passive: at once');
assert.equal(jumped(un).length, 0, 'uncharged: not yet');
assert.ok(h.runUntil(() => jumped(un).length > 0, idle + 1), 'uncharged: after the idle time');
assert.ok(h.b.time >= idle - 1e-6, `at ${h.b.time.toFixed(2)} s`);
checkInvariants(h.b);
});
test('不屈: knocked-out 地面干员 (melee position) redeploys (p=1 at high L); tier 2 every operator +5 SP; inactive / ranged → no', () => {
const bb = bondBb('indomShip');
const sk = { spCost: 50, initSp: 0 };
+92
View File
@@ -0,0 +1,92 @@
// test/content/feedback5-regen.test.js — 生命回复速度 is not 治疗 (GitHub #96 / #137). Effects PRTS describes as raising the
// target's 「生命回复速度」 attribute — the 吟游者 trait (分支特性信息 吟游者; 魔王, 浊心斯卡蒂), 调香师's 熏衣草, 瑕光 S2, 铃兰 S3 —
// are hpRegen buffs: 无法被友方治疗 (隐德来希 收割者, 折桠 不屈者) and 禁疗 do not stop them, 治疗加成 does not scale them
// (damage.js heal `regen`); a direct heal is still refused / scaled as before.
// Run: node --test test/content/feedback5-regen.test.js
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { makeBattle, chessRec, checkInvariants } from '../helpers/battleHarness.js';
const REAPER = 'chess_char_5_06_a', UNYIELD = 'chess_char_2_17_a';
const DEFS = { chess: { t_plain: chessRec({ id: 't_plain', profession: 'TANK', skill: null, stats: { maxHp: 10000, atk: 0, def: 0 } }) } };
/** Provider on (10,4) facing right with 隐德来希 on (10,5) and 折桠 on (11,4) at half HP (both "无法被友方角色治疗"). */
function field(provider, extra = []) {
const h = makeBattle({
defs: DEFS, autoFinish: false, timeLimit: 120,
units: [{ row: 10, col: 4, ...provider }, { chessId: REAPER, row: 10, col: 5 }, { chessId: UNYIELD, row: 11, col: 4 }, ...extra],
});
h.step();
const p = h.unit(provider.chessId), r = h.unit(REAPER), z = h.unit(UNYIELD);
for (const x of [r, z]) x.hp = x.s.maxHp * 0.5;
return { h, p, r, z };
}
/** HP gained over `secs` s against the unit's own 生命回复速度 (at most ~1 HP pending in the regeneration tick). */
function regenOver(h, u, secs) {
const hp0 = u.hp, rate = u.s.hpRegen;
h.run(secs);
return { gained: u.hp - hp0, expected: rate * secs, rate };
}
const PROVIDERS = [
// [label, unit entry, prepare(h, p) → buff key of the provider's 生命回复速度]
['魔王 trait (吟游者)', { chessId: 'chess_char_4_25_a' }, (h, p) => `trait:bard:${p.id}`],
['浊心斯卡蒂 trait (吟游者, S2 loadout: on, trait raised)', { chessId: 'chess_char_6_04_a', skillIndex: 1, carryState: { sp: 999 } }, (h, p) => {
assert.ok(h.runUntil(() => p.skill.active, 5));
return `trait:bard:${p.id}`;
}],
['调香师 熏衣草', { chessId: 'chess_char_2_14_a' }, (h, p) => `flower:lavender:${p.id}`],
['瑕光 S2 慑敌辉光', { chessId: 'chess_char_3_12_a', skillIndex: 1 }, (h, p) => { assert.ok(p.skill.activate('test', { free: true })); return `blemsh:regen:${p.id}`; }],
['铃兰 S3 狐火渺然', { chessId: 'chess_char_5_10_a' }, (h, p) => { assert.ok(p.skill.activate('test', { free: true })); h.run(1.05); return `lisa:fox:${p.id}`; }],
];
test('隐德来希 (收割者) and 折桠 (不屈者) regenerate under 魔王 / 浊心斯卡蒂 / 调香师 / 瑕光 S2 / 铃兰 S3 — none of it is a heal; a direct heal from the same provider is still refused', () => {
for (const [label, entry, prepare] of PROVIDERS) {
const { h, p, r, z } = field(entry);
const key = prepare(h, p);
h.run(1.2); // (the providers' own talent auras settle their ATK first)
for (const x of [r, z]) {
const b = x.findBuff(key);
assert.ok(b && b.mods.hpRegen > 0, `${label}: ${x.defId} carries the 生命回复速度 buff`);
const { gained, expected } = regenOver(h, x, 2);
assert.ok(gained > 0 && Math.abs(gained - expected) <= 1.5, `${label}: ${x.defId} +${gained.toFixed(2)} ≈ ${expected.toFixed(2)}`);
assert.equal(h.b.heal(p, x, 100), 0, `${label}: a direct heal on ${x.defId} is still refused (无法被友方角色治疗)`);
}
assert.equal(h.hooksOf('heal').filter((c) => c.source === p && (c.target === r || c.target === z)).length, 0, `${label}: no heal of the provider reached them`);
checkInvariants(h.b);
assert.equal(h.b.errors.length, 0);
}
});
test('禁疗 does not stop 生命回复速度 (异常效果 禁疗 「增减生命回复速度…的效果不会被识别为治疗类能力」); it still stops heals, the unit\'s own included', () => {
const { h, p } = field({ chessId: 'chess_char_2_14_a' }, [{ chessId: 't_plain', row: 9, col: 4 }]);
const t = h.unit('t_plain');
h.b.addBuff(t, { key: 'test:healFree', status: 'healFree', flags: { noHeal: true, healFree: true } });
t.hp = 4000;
h.run(0.6);
const { gained, expected } = regenOver(h, t, 2);
assert.ok(gained > 0 && Math.abs(gained - expected) <= 1.5, `under 禁疗: +${gained} ≈ ${expected}`);
assert.equal(h.b.heal(p, t, 100), 0, 'a heal from her: refused');
assert.equal(h.b.heal(t, t, 100, { self: true }), 0, 'its own heal: 0 under 禁疗');
checkInvariants(h.b);
});
test('治疗加成 does not scale 生命回复速度: a healing-received multiplier and 百炼嘉维尔\'s 医学背景 (a heal hook) leave the regeneration as it is; a direct heal is scaled', () => {
const { h, p } = field({ chessId: 'chess_char_2_14_a' }, [{ chessId: 't_plain', row: 9, col: 4 }, { chessId: 'chess_char_4_23_a', row: 12, col: 4 }]);
const t = h.unit('t_plain'), gv = h.unit('chess_char_4_23_a');
h.b.addBuff(t, { key: 'test:healUp', mods: { healingTakenMul: 1.5 } });
t.hp = 4000;
gv.hp = gv.s.maxHp * 0.3; // 医学背景: healing received ×1.4 below half HP
h.run(0.6);
const v = p.s.atk * p.def.talents[0].bb.atk_to_hp_recovery_ratio;
for (const x of [t, gv]) {
assert.ok(Math.abs(x.s.hpRegen - x.base.hpRecoveryPerSec - v) < 1e-6, `${x.defId}: 生命回复速度 +ATK × ratio, unscaled`);
const { gained, expected } = regenOver(h, x, 2);
assert.ok(Math.abs(gained - expected) <= 1.5, `${x.defId}: +${gained} ≈ ${expected} (no ×1.5 / ×1.4)`);
}
assert.ok(Math.abs(h.b.heal(p, t, 100) - 150) < 1e-6, 'a heal: ×1.5 healing received');
assert.ok(h.b.heal(p, gv, 100) > 100 + 1e-6, 'a heal on 百炼嘉维尔: her 医学背景 applies');
checkInvariants(h.b);
});
+8 -5
View File
@@ -565,7 +565,7 @@ test('3_12 瑕光 S1 光芒涌动 (自动触发 ⇒ DEFAULT, charges): next atta
}
});
test('3_12 瑕光 S2 慑敌辉光: ATK +, ground enemies on her tile sleep for the skill, allies of the skill range healed each second', () => {
test('3_12 瑕光 S2 慑敌辉光: ATK +, ground enemies on her tile sleep for the skill, allies of the skill range get 生命回复速度 (PRTS 备注: no heal)', () => {
for (const id of BOTH('chess_char_3_12_a')) {
const b = SB(id, 'skchr_blemsh_2'), t1 = TB(id, 1);
const dur = LD(id, 'skchr_blemsh_2').skill.duration;
@@ -586,14 +586,17 @@ test('3_12 瑕光 S2 慑敌辉光: ATK +, ground enemies on her tile sleep for t
assert.ok(e.s.flags.sleep, 'her tile: asleep');
approx(e.findBuff('sleep').timeLeft, dur - h.b.dt, 0.05, 'for the skill duration');
assert.ok(!n.s.flags.sleep, 'next tile: awake');
const n0 = h.hooksOf('damaged').length;
const v = u.s.atk * b['attack@atk_to_hp_recovery_ratio'];
approx(ally.findBuff(`blemsh:regen:${u.id}`)?.mods.hpRegen ?? 0, v, 1e-6, '生命回复速度 +ATK × ratio');
const n0 = h.hooksOf('damaged').length, hp0 = ally.hp, t1s = h.b.time, own = ally.s.hpRegen - v;
h.run(2.2);
const onSleeper = h.hooksOf('damaged').slice(n0).filter((c) => c.source === u && c.target === e && c.dmg?.isAttack);
assert.ok(onSleeper.length >= 1, '仁慈: she hits the sleeper');
approx(onSleeper[0].amount, u.s.atk * t1.atk_scale, 1e-6, '×仁慈');
const regen = h.hooksOf('heal').filter((c) => c.source === u && c.target === ally);
assert.equal(regen.length, 2, 'once per second');
approx(regen[0].amount, u.s.atk * b['attack@atk_to_hp_recovery_ratio']);
assert.equal(h.hooksOf('heal').filter((c) => c.source === u && c.target === ally).length, 0, 'no heal of hers');
assert.ok(Math.abs(ally.hp - hp0 - (v + own) * (h.b.time - t1s)) <= 1.5, `regenerated ${ally.hp - hp0}`);
assert.ok(h.runUntil(() => !u.skill.active, dur + 1));
assert.equal(ally.findBuff(`blemsh:regen:${u.id}`), null, 'gone with the skill');
done(h);
}
});
+9 -7
View File
@@ -313,7 +313,7 @@ test('6_03 余 S2 厚礼上宾: cast with an enemy on its x-1 (SKILL_RANGE — a
// =================================================================================================================
// 6_04 浊心斯卡蒂
test('6_04 浊心斯卡蒂 S1 同归殊途之吟: SP_FULL, full HP + max HP +; trait heal raised; 50 % of the damage of allies in range goes to her', () => {
test('6_04 浊心斯卡蒂 S1 同归殊途之吟: SP_FULL, full HP + max HP +; trait (生命回复速度) raised; 50 % of the damage of allies in range goes to her', () => {
for (const id of both('chess_char_6_04')) {
const sid = 'skchr_skadi2_1', bb = bbOf(id, sid);
const h = run({
@@ -333,14 +333,14 @@ test('6_04 浊心斯卡蒂 S1 同归殊途之吟: SP_FULL, full HP + max HP +; t
approx(onAlly[0].amount, 1000 * (1 - bb.damage_resistance), 'the ally takes the rest');
approx(onHer[0].amount, 1000 * bb.damage_resistance, 'she takes the transferred part');
assert.equal(onHer[0].type, 'true');
const hh = heals(h, u, (c) => c.target === a && c.opts?.aura);
assert.ok(hh.length > 0);
approx(hh[hh.length - 1].amount, u.s.atk * bb['attack@atk_to_hp_recovery_ratio'], 'trait heal raised');
// the trait is an hpRegen buff on the ally (PRTS 分支特性信息 吟游者; professions.js bardRegen), no heal of hers
approx(a.findBuff(`trait:bard:${u.id}`)?.mods.hpRegen ?? 0, u.s.atk * bb['attack@atk_to_hp_recovery_ratio'], 'trait raised');
assert.equal(heals(h, u, (c) => c.target === a).length, 0, 'no heal of hers');
done(h);
}
});
test('6_04 浊心斯卡蒂 S2 同葬无光之愿: toggle; 鼓舞 ATK and DEF (atk / def × hers) on the other allies of her range, trait heal 16/17 %', () => {
test('6_04 浊心斯卡蒂 S2 同葬无光之愿: toggle; 鼓舞 ATK and DEF (atk / def × hers) on the other allies of her range, trait 16/17 % (生命回复速度)', () => {
for (const id of both('chess_char_6_04')) {
const sid = 'skchr_skadi2_2', bb = bbOf(id, sid);
const h = run({
@@ -359,9 +359,11 @@ test('6_04 浊心斯卡蒂 S2 同葬无光之愿: toggle; 鼓舞 ATK and DEF (at
approx(a.s.def, a.base.def + u.s.def * bb.def, 'DEF raised by the flat value', 1e-3);
assert.ok(!u.findBuff('inspire') && !u.findBuff('inspire:def'), 'never on herself');
a.hp = a.s.maxHp * 0.5;
const hp0 = a.hp, t1 = h.b.time;
h.run(1.1);
const hh = heals(h, u, (c) => c.target === a && c.opts?.aura);
approx(hh[hh.length - 1].amount, u.s.atk * bb['attack@atk_to_hp_recovery_ratio'], 'trait heal ratio');
const v = u.s.atk * bb['attack@atk_to_hp_recovery_ratio'];
approx(a.findBuff(`trait:bard:${u.id}`)?.mods.hpRegen ?? 0, v, 'trait ratio');
assert.ok(Math.abs(a.hp - hp0 - (a.s.hpRegen) * (h.b.time - t1)) <= 1.5, `regenerated ${a.hp - hp0}`);
done(h);
}
});
+26 -8
View File
@@ -496,7 +496,7 @@ test('1_15 盟约·辅助干员 (hidden): 迭代元素 18 % ATK 神经 + 灼燃
});
for (const [idA, idB] of [['chess_char_1_16_a', 'chess_char_1_16_b'], ['chess_char_2_19_a', 'chess_char_2_19_b']]) {
test(`${idA.slice(11, 15)} 锡人: “大拉里” zone — ground enemies take atk_scale × ATK arts/s, allies heal; elite 凋敝魂灵 + module SP`, () => {
test(`${idA.slice(11, 15)} 锡人: “大拉里” zone — ground enemies take atk_scale × ATK arts/s, allies inside get 生命回复速度 (PRTS 备注: no heal); elite 凋敝魂灵 + module SP`, () => {
const bb = bbOf(idA);
const flyer = dummy('e_fly', { motion: 'FLY' });
const h = run({
@@ -513,10 +513,25 @@ for (const [idA, idB] of [['chess_char_1_16_a', 'chess_char_1_16_b'], ['chess_ch
assert.equal(z.length, bb.projectile_delay_time);
for (const c of z) approx(c.amount, u.s.atk * bb.atk_scale);
assert.equal(dealt(h, u, (c) => c.target === f && (c.dmg.tags || []).includes('zone')).length, 0, 'air units unaffected');
const zh = heals(h, u, (c) => c.target === yak);
assert.equal(zh.length, bb.projectile_delay_time);
for (const c of zh) approx(c.amount, u.s.atk * bb.hp_recovery_per_sec_ratio);
assert.equal(heals(h, u, (c) => c.target === yak).length, 0, 'no heal of hers: an hpRegen buff (PRTS 备注 「增加目标的“生命回复速度”属性」)');
done(h);
// the ally inside: 生命回复速度 + her ATK at the cast × hp_recovery_per_sec_ratio for the unit's life, then gone
const h3 = run({
defs: { enemies: { e: dummy('e') } },
units: [{ chessId: idA, row: 10, col: 4, carryState: READY }, { chessId: 'chess_char_1_02_a', row: 10, col: 6 }],
enemies: [{ key: 'e', pos: [10, 5] }],
});
const u3 = h3.unit(idA), yak3 = h3.unit('chess_char_1_02_a');
const zone = () => yak3.buffs.find((b) => String(b.key).startsWith('tinman:zone:'));
assert.ok(h3.runUntil(() => !!zone(), 2), 'the unit is down');
const v = u3.s.atk * bb.hp_recovery_per_sec_ratio;
approx(zone().mods.hpRegen, v, 'ATK × ratio');
yak3.hp = yak3.s.maxHp * 0.3;
const hp0 = yak3.hp, t1 = h3.b.time;
h3.run(5);
assert.ok(Math.abs(yak3.hp - hp0 - v * (h3.b.time - t1)) <= 1.5, `regenerated ${yak3.hp - hp0} ≈ ${v * 5}`);
assert.ok(h3.runUntil(() => !zone(), bb.projectile_delay_time + 1), 'gone with the unit');
done(h3);
const bbB = bbOf(idB), w = tal(idB, 1)['skill@damage_scale'], mb = hid(idB);
const h2 = run({ defs: { enemies: { e: dummy('e') } }, units: [{ chessId: idB, row: 10, col: 4 }], enemies: [{ key: 'e', pos: [10, 5] }] });
@@ -1018,7 +1033,7 @@ test('2_13 蒂比: an incoming attack triggers 紧急赶场通知 and is dodged;
done(h2);
});
test('2_14 调香师: 精调 ATK +atk / ASPD −50; 熏衣草 heals every ally atk_to_hp_recovery_ratio × ATK per s; elite heals 4', () => {
test('2_14 调香师: 精调 ATK +atk / ASPD −50; 熏衣草 every ally 生命回复速度 +atk_to_hp_recovery_ratio × ATK (PRTS 备注: no heal); elite heals 4', () => {
const id = 'chess_char_2_14_a', bb = bbOf(id), t = tal(id);
const h = run({ units: [{ chessId: id, row: 10, col: 4, carryState: READY }, { chessId: 'chess_char_1_02_a', row: 9, col: 9 }, { chessId: 'chess_char_1_10_a', row: 10, col: 5 }] });
const u = h.unit(id), far = h.unit('chess_char_1_02_a'), near = h.unit('chess_char_1_10_a');
@@ -1029,9 +1044,12 @@ test('2_14 调香师: 精调 ATK +atk / ASPD −50; 熏衣草 heals every ally a
assert.ok(u.skill.active);
approx(u.s.atk, u.base.atk * (1 + bb.atk));
approx(u.s.aspd, u.base.aspd + bb.attack_speed);
const aura = heals(h, u, (c) => c.target === far);
assert.equal(aura.length, 3, 'one pulse per second, out of range too');
for (const c of aura) approx(c.amount, u.s.atk * t.atk_to_hp_recovery_ratio);
const v = u.s.atk * t.atk_to_hp_recovery_ratio;
for (const x of [far, near, u]) approx(x.s.hpRegen - x.base.hpRecoveryPerSec, v, `${x.defId}: 生命回复速度 +ATK × ratio (out of range too)`);
assert.equal(heals(h, u, (c) => c.target === far).length, 0, 'no heal of hers');
const hp0 = far.hp, t1 = h.b.time;
h.run(2);
assert.ok(Math.abs(far.hp - hp0 - far.s.hpRegen * (h.b.time - t1)) <= 1.5, `regenerated ${far.hp - hp0}`);
done(h);
const idb = 'chess_char_2_14_b';
const ids = ['chess_char_1_02_a', 'chess_char_1_10_a', 'chess_char_1_12_a', 'chess_char_2_07_a', 'chess_char_1_18_a'];
+8 -8
View File
@@ -855,7 +855,7 @@ test('卡涅利安 / 蜜蜡 elite trait: keep DEF +100 % / RES +10 during the sk
}
});
test('魔王 S3: range up, trait heal 65 % ATK/s, 鼓舞 +65 % of her max HP, HP redistributed every 2 s; motes ×1.5; 萨卡兹 −10 %', () => {
test('魔王 S3: range up, trait 65 % ATK/s (生命回复速度), 鼓舞 +65 % of her max HP, HP redistributed every 2 s; motes ×1.5; 萨卡兹 −10 %', () => {
const id = 'chess_char_4_25_a', bb = D(id).skill.bb, t0 = D(id).talents[0].bb, t1 = D(id).talents[1].bb;
const sarkaz = withTags(dummy({ key: 'enemy_sarkaz' }), ['sarkaz']);
const h = makeBattle({ defs: { enemies: { enemy_sarkaz: sarkaz } }, units: [{ chessId: id, row: 10, col: 5 }, { chessId: 'chess_char_1_02_a', row: 10, col: 6 }, { chessId: 'chess_char_4_17_a', row: 9, col: 5 }],
@@ -868,10 +868,11 @@ test('魔王 S3: range up, trait heal 65 % ATK/s, 鼓舞 +65 % of her max HP, HP
const n0 = noisy(h, 'damaged').length;
h.b.dealDamage(e, a, { amount: 1000, type: 'true' });
approx(noisy(h, 'damaged')[n0].amount, 1000 * (1 - t1.damage_resistance), 1e-9);
// trait heal ×1.5 with a mote
h.runUntil(() => noisy(h, 'heal').some((c) => c.source === u && c.target === a), 3);
const hl = noisy(h, 'heal').find((c) => c.source === u && c.target === a);
approx(hl.amount, u.s.atk * D(id).traitBb['attack@atk_to_hp_recovery_ratio'] * t0['attack@trait_mul'] * a.s.healingTakenMul, 1e-6);
// the trait: 生命回复速度 (an hpRegen buff — PRTS 分支特性信息 吟游者; professions.js bardRegen), ×1.5 with a mote
const trait = (x) => x.findBuff(`trait:bard:${u.id}`)?.mods.hpRegen ?? 0;
h.run(0.3);
approx(trait(a), u.s.atk * D(id).traitBb['attack@atk_to_hp_recovery_ratio'] * t0['attack@trait_mul'], 1e-6, 'trait ×1.5 with a mote');
assert.equal(noisy(h, 'heal').filter((c) => c.source === u && c.target === a).length, 0, 'no heal of hers');
// S3
h.b.dealDamage(null, b, { amount: b.s.maxHp * 0.7, type: 'true' });
assert.ok(u.skill.activate('test', { free: true }));
@@ -882,9 +883,8 @@ test('魔王 S3: range up, trait heal 65 % ATK/s, 鼓舞 +65 % of her max HP, HP
for (let i = 0; i < 90 && !redistributed; i++) { h.step(); redistributed = h.events.some((ev) => ev[0] === 'fx' && ev[1] === 'redistribute'); }
assert.ok(redistributed);
approx(a.hpRatio, b.hpRatio, 1e-9, 'equal HP ratios after redistribution');
h.runUntil(() => noisy(h, 'heal').filter((c) => c.source === u && c.target === b && c.t > 0.8).length >= 1, 3);
const sh = noisy(h, 'heal').filter((c) => c.source === u && c.target === b).pop();
approx(sh.amount, u.s.atk * bb['attack@atk_to_hp_recovery_ratio'] * t0['attack@trait_mul'] * b.s.healingTakenMul, 1e-6, 'trait 65 %');
h.run(0.3);
approx(trait(b), u.s.atk * bb['attack@atk_to_hp_recovery_ratio'] * (b.findBuff(`cetsyr:mote:${u.id}`) ? t0['attack@trait_mul'] : 1), 1e-6, 'trait 65 %');
h.runUntil(() => !u.skill.active, 40);
h.run(0.3);
approx(a.s.maxHp, a.base.maxHp, 1e-9, '鼓舞 gone');
+22 -8
View File
@@ -457,7 +457,7 @@ test('号角 S3: cast with an enemy in range (DEFAULT, DESIGN §21.29); ATK +25
});
// ------------------------------------------------------------------------------------------------------------------
test('魔王 S3: inspire +65 % of her max HP to others in range, HP equalised every 2 s; T1 orbiting motes ×1.5 aura heal; T2 −10 % from Sarkaz', () => {
test('魔王 S3: inspire +65 % of her max HP to others in range, HP equalised every 2 s; T1 orbiting motes ×1.5 trait (生命回复速度); T2 −10 % from Sarkaz', () => {
const sark = dummy('enemy_sark');
sark.tags = ['sarkaz'];
const h = makeBattle({
@@ -469,17 +469,22 @@ test('魔王 S3: inspire +65 % of her max HP to others in range, HP equalised ev
const a = h.unit('t_a'), b = h.unit('t_b'), c = h.unit('t_c');
const bb = bbOf(u), t0 = tal(u, 0), t1 = tal(u, 1);
const aura = () => u.s.atk * u.def.traitBb['attack@atk_to_hp_recovery_ratio'];
// the trait: 生命回复速度 on the allies in range (an hpRegen buff — PRTS 分支特性信息 吟游者; professions.js bardRegen)
const trait = (x) => x.findBuff(`trait:bard:${u.id}`)?.mods.hpRegen ?? 0;
h.step();
a.hp = 2000; b.hp = 8000; c.hp = 2000;
h.run(1.05);
// the 3 motes orbit at range_radius 1.15 (dynamic_spd 30°/s, 120° apart): none sits on the left neighbour at t = 1 s
assert.ok(!a.hasBuff('cetsyr:mote'), 'motes orbit: not on the left neighbour yet');
approx(a.hp - 2000, aura(), 1e-6, 'plain aura before the mote arrives');
approx(b.hp - 8000, aura(), 1e-6, 'plain aura (2 tiles away)');
approx(trait(a), aura(), 1e-6, 'plain trait before the mote arrives');
approx(trait(b), aura(), 1e-6, 'plain trait (2 tiles away)');
assert.ok(a.hp > 2000 && b.hp > 8000, 'regenerating');
assert.ok(h.runUntil(() => a.hasBuff('cetsyr:mote'), 2), 'an orbiting mote reaches the adjacent operator');
h.run(0.3);
approx(trait(a), aura() * t0['attack@trait_mul'], 1e-6, 'mote ×1.5');
const hpA = a.hp;
h.run(1);
approx(a.hp - hpA, aura() * t0['attack@trait_mul'], 1e-6, 'mote ×1.5');
assert.ok(Math.abs(a.hp - hpA - aura() * t0['attack@trait_mul']) <= 1.5, `mote ×1.5: +${a.hp - hpA} in 1 s`);
assert.ok(h.runUntil(() => c.hasBuff('cetsyr:mote'), 12), 'a diagonal neighbour (1.41 tiles) is on the orbit too');
h.run(8);
assert.ok(!fxOf(h, 'mote').some((e) => e[4].id === b.id), 'two tiles away: off the orbit');
@@ -502,7 +507,7 @@ test('魔王 S3: inspire +65 % of her max HP to others in range, HP equalised ev
});
// ------------------------------------------------------------------------------------------------------------------
test('铃兰 T2 画地为牢 fragile 20 % on sluggish enemies (×1.4 in S3); S3 no attack, range-wide sluggish, heals; T1 Supporter SP aura', () => {
test('铃兰 T2 画地为牢 fragile 20 % on sluggish enemies (×1.4 in S3); S3 no attack, range-wide sluggish, 生命回复速度 (none in the first second); T1 Supporter SP aura', () => {
const h = makeBattle({
defs: { enemies: { enemy_dummy: dummy() }, chess: { t_sup: chessRec({ id: 't_sup', profession: 'SUPPORT', stats: { atk: 0 } }), t_hurt: ally('t_hurt') } },
units: [{ chessId: 'chess_char_5_10_a', row: 10, col: 4 }, { chessId: 't_sup', row: 12, col: 3 }, { chessId: 't_hurt', row: 11, col: 5 }],
@@ -521,12 +526,21 @@ test('铃兰 T2 画地为牢 fragile 20 % on sluggish enemies (×1.4 in S3); S3
hurt.hp = 5000;
u.skill.gainSp(1000);
assert.ok(h.runUntil(() => u.skill.active, 5));
const lastAtk = u.lastAttackAt;
h.run(2.1);
const lastAtk = u.lastAttackAt, cast = h.b.time;
// PRTS 技能3 备注: an hpRegen buff (no heal), 0 in the first second, its amount refreshed every second
const fox = () => hurt.findBuff(`lisa:fox:${u.id}`);
h.run(0.9);
assert.equal(fox(), null, 'nothing in the first second');
assert.equal(hurt.hp, 5000);
h.run(1.2);
assert.equal(u.lastAttackAt, lastAtk, 'no attacks during S3');
assert.ok(e.s.flags && e.findBuff('sluggish'), 'enemies in range are sluggish');
approx(e.s.dmgTakenMul, 1 + (t1.damage_scale - 1) * bb.scale_delta_to_one, 1e-9, 'T2 ×1.4');
approx(hurt.hp - 5000, 2 * u.s.atk * bb['attack@atk_to_hp_recovery_ratio'], 1e-6, 'heals 9 % ATK/s');
const v = u.s.atk * bb['attack@atk_to_hp_recovery_ratio'];
approx(fox().mods.hpRegen, v, 1e-9, '生命回复速度 +9 % ATK');
assert.ok(Math.abs(hurt.hp - 5000 - v * (h.b.time - cast - 1)) <= 2, `regenerated ${hurt.hp - 5000} from the first second on`);
assert.ok(h.runUntil(() => !u.skill.active, 40));
assert.equal(fox(), null, 'gone with the skill');
clean(h);
});
+94 -4
View File
@@ -24,6 +24,7 @@ const DEFS = {
test_tank2_a: chessRec({ id: 'test_tank2_a', profession: 'TANK', stats: { maxHp: 100000, atk: 1, def: 0 }, skill: null }),
// SP only from 攫升: an attack-SP skill and no enemy to attack
test_sp_a: chessRec({ id: 'test_sp_a', profession: 'TANK', stats: { maxHp: 100000, atk: 1, def: 0 }, skill: { spType: 'INCREASE_WHEN_ATTACK', spCost: 1000, initSp: 0 } }),
test_sp2_a: chessRec({ id: 'test_sp2_a', profession: 'TANK', stats: { maxHp: 1000, atk: 1, def: 0 }, skill: { spType: 'INCREASE_WHEN_ATTACK', spCost: 1000, initSp: 0 } }),
test_medic_a: chessRec({ id: 'test_medic_a', profession: 'MEDIC', subProfessionId: 'physician', stats: { atk: 300 }, skill: null, rangeGrid: [[0, 0]] }),
},
};
@@ -97,9 +98,9 @@ test('S3 恳切福音: cast with an injured ally inside the 5-2 only (no heal be
h.run(0.5);
const first = h.heals.filter((x) => x.t === h.heals[0].t);
assert.ok(first[0].t >= cast, `${id}: the first heal comes with the cast`);
assert.deepEqual(first.map((x) => x.uid), [2, 2], `${id}: the main heal on the far ally, then the extra on it (its neighbours are full)`);
assert.deepEqual(first.map((x) => x.uid), [2, 2], `${id}: the main heal on the far ally, then the extra on it (the lowest HP ratio of it and its neighbours)`);
close(first[0].amount, u.s.atk * phy * boost, `${id}: main heal ×${boost}${phy > 1 ? ' ×1.15 PHY-X' : ''}`);
close(first[1].amount, first[0].amount * 0.3, `${id}: extra heal = 30 % of the main one`);
close(first[1].amount, u.s.atk * 0.3 * phy * boost, `${id}: extra heal = 30 % of the main heal's base, its still-low recipient's bonuses on it`);
// two injured allies: both healed per action
h.b.loseHp(near, near.hp * 0.2);
const n0 = h.heals.length;
@@ -121,6 +122,41 @@ test('S3 恳切福音: cast with an injured ally inside the 5-2 only (no heal be
}
});
test('S3 extra heal (PRTS 备注): 30 % of the main heal\'s base, its own recipient\'s ×heal_scale (and PHY-X); the lowest HP ratio of the main target and its 4 neighbours; exactly half HP is not 「低于」', () => {
for (const id of ['chess_char_5_11_a', 'chess_char_6_09_b']) {
const phy = moduleOf(id) ? 1.15 : 1;
const boost = skillOf(id, S3).bb.heal_scale;
// the main target on (10,8) (inside the 5-2, outside her 3-3); its neighbour (10,9) is beyond the 5-2 (never a main target)
const firstAction = (mainRatio, nearRatio) => {
const h = battle({ id, carry: { sp: 999 } }, [['test_tank_a', 10, 8, mainRatio], ['test_tank2_a', 10, 9, nearRatio]]);
const u = h.unit(1);
assert.ok(h.runUntil(() => h.heals.length >= 2, 5), `${id}: healed`);
assert.ok(u.skill.active, `${id}: S3 running`);
const t0 = h.heals[0].t;
const act = h.heals.filter((x) => x.t === t0);
assert.equal(act.length, 2, `${id}: one main heal and one extra heal`);
checkInvariants(h.b);
return { u, main: act[0], extra: act[1] };
};
// main above half: no bonus; the extra goes to the neighbour below half (lower ratio), with both bonuses
let r = firstAction(0.55, 0.45);
assert.deepEqual([r.main.uid, r.extra.uid], [2, 3], `${id}: the extra on the lower-ratio neighbour`);
close(r.main.amount, r.u.s.atk, `${id}: no bonus at 55 %`);
close(r.extra.amount, r.u.s.atk * 0.3 * boost * phy, `${id}: the extra takes its own recipient's ×${boost}`);
// main at exactly half: "低于" — no ×heal_scale, no PHY-X; the extra on it (its neighbour is full), no bonus either
r = firstAction(0.5, 1);
assert.deepEqual([r.main.uid, r.extra.uid], [2, 2], `${id}: the full neighbour has the higher ratio`);
close(r.main.amount, r.u.s.atk, `${id}: exactly 50 % is not below half`);
close(r.extra.amount, r.u.s.atk * 0.3, `${id}: extra = 30 % of the base`);
// main just below half: boosted; the extra lands on it after it crossed half — 30 % of the base, not of the boosted heal
r = firstAction(0.499, 1);
assert.deepEqual([r.main.uid, r.extra.uid], [2, 2]);
close(r.main.amount, r.u.s.atk * boost * phy, `${id}: ×${boost} below half`);
assert.ok(r.extra.ratio >= 0.5, `${id}: its recipient is above half now`);
close(r.extra.amount, r.u.s.atk * 0.3, `${id}: the extra's base excludes the main heal's bonuses`);
}
});
test('S1 慨赠: cast on an injured ally in her range; 20 s of ATK +40 % / +50 %, each heal a 40 % / 50 % chance of a second heal of the same ally', () => {
for (const [id, atk, p] of [['chess_char_5_11_a', 0.4, 0.4], ['chess_char_5_11_b', 0.5, 0.5]]) {
assert.deepEqual([skillOf(id, S1).bb.atk, skillOf(id, S1).bb['attack@prob'], skillOf(id, S1).duration], [atk, p, 20]);
@@ -187,9 +223,9 @@ test('S2 宛如天启: cast with an injured ally inside the 3-10 only; 30 s on t
assert.equal(h.unit(1).skill.activations, 0);
});
test('攫升 / 超脱 (the strategy\'s mapCharTalents): a healed unit +3 SP; an operator knocked out in her range +5 SP (+8 with PHY-X Lv3)', () => {
test('攫升 / 超脱 (the strategy\'s mapCharTalents): a healed unit +3 SP; an operator knocked out — or forced out — in her range +5 SP (+8 with PHY-X Lv3)', () => {
for (const [id, sp] of [['chess_char_5_11_a', 5], ['chess_char_5_11_b', 5], ['chess_char_6_20_b', 8]]) {
const h = battle({ id }, [['test_sp_a', 10, 5, 0.6], ['test_tank_a', 9, 4, 1], ['test_tank2_a', 9, 10, 1]]);
const h = battle({ id }, [['test_sp_a', 10, 5, 0.6], ['test_tank_a', 9, 4, 1], ['test_tank2_a', 9, 10, 1], ['test_tank_a', 11, 4, 1], ['test_tank2_a', 11, 5, 1], ['test_tank_a', 9, 5, 1], ['test_tank2_a', 11, 6, 1]]);
const u = h.unit(1), ally = h.unit(2);
const gains = [];
h.b.on('spGain', (c) => { if (c.unit === ally) gains.push([c.reason, c.amount]); });
@@ -203,6 +239,60 @@ test('攫升 / 超脱 (the strategy\'s mapCharTalents): a healed unit +3 SP; an
const mid = u.skill.sp;
h.b.kill(h.unit(4)); // (9,10): out of it
close(u.skill.sp, mid, `${id}: not out of range`);
// PRTS 备注: a forced exit with a death animation (史尔特尔's 余烬: a `dying` retreat) counts; not a skill's planned
// retreat (耀骑士临光 S2, 伊内丝 S3: a plain 'retreat'), the 商人's automatic 撤退 ('merchant') or the 突袭 jump ('raid')
h.b.retreat(h.unit(5), { reason: 'retreat', dying: true }); // (11,4)
close(u.skill.sp, mid + sp, `${id}: 超脱 on a dying forced exit`);
h.b.retreat(h.unit(6), { reason: 'retreat' }); // (11,5)
h.b.retreat(h.unit(7), { reason: 'merchant' }); // (9,5)
h.b.retreat(h.unit(8), { reason: 'raid' }); // (11,6)
close(u.skill.sp, mid + sp, `${id}: not on a planned, a 商人's or a 突袭 retreat`);
checkInvariants(h.b);
}
});
test('超脱 on 史尔特尔\'s 余烬 exit (PRTS 备注 "如史尔特尔的天赋效果"): her forced exit 8 s after the lethal blow gives Touch the SP', () => {
const id = 'chess_char_5_11_a', sp = 5;
const h = battle({ id }, [['chess_char_5_07_a', 9, 4, 1]]);
const u = h.unit(1), surtr = h.unit(2);
const exits = [];
h.b.on('death', (c) => { if (c.unit === surtr) exits.push([c.reason, c.dying]); });
h.b.dealDamage(null, surtr, { amount: 1e7, type: 'true' });
assert.ok(surtr.alive && surtr.findBuff('surtr:ember'), '余烬: kept alive');
const before = u.skill.sp;
const gains = [];
h.b.on('spGain', (c) => { if (c.unit === u && c.reason === 'talent') gains.push(c.amount); });
assert.ok(h.runUntil(() => !surtr.alive, 12), 'she withdraws');
assert.deepEqual(exits, [['retreat', true]], 'a dying forced exit');
assert.deepEqual(gains, [sp], '超脱');
assert.ok(u.skill.sp >= before + sp - 1e-6);
checkInvariants(h.b);
});
test('攫升 (PRTS 备注 "只需Touch输出治疗便能触发(无需实际产生治疗量)"): her heal on herself and a heal that restores nothing (S3\'s extra heal on a full unit) give SP too', () => {
for (const id of ['chess_char_5_11_a', 'chess_char_6_09_b']) {
// herself: injured, she heals herself (her 3-3 holds her own tile)
let h = battle({ id }, []);
let u = h.unit(1);
h.b.loseHp(u, u.hp * 0.4);
const own = [];
h.b.on('spGain', (c) => { if (c.unit === u && c.reason === 'talent') own.push(c.amount); });
assert.ok(h.runUntil(() => h.heals.length > 0, 5), `${id}: a self-heal`);
h.step();
assert.equal(h.heals[0].uid, 1);
assert.deepEqual(own, [3], `${id}: 攫升 on her own heal`);
checkInvariants(h.b);
// S3: the main heal fills a 1000-HP unit at 90 %, then the extra heal lands on it at full HP — still +3 SP
h = battle({ id, carry: { sp: 999 } }, [['test_sp2_a', 10, 8, 0.9]]);
u = h.unit(1);
const tgt = h.unit(2);
const got = [];
h.b.on('spGain', (c) => { if (c.unit === tgt && c.reason === 'talent') got.push(c.amount); });
assert.ok(h.runUntil(() => h.heals.length >= 2, 5), `${id}: S3 heals`);
h.step();
assert.ok(u.skill.active);
assert.deepEqual(h.heals.slice(0, 2).map((x) => [x.uid, x.ratio === 1]), [[2, false], [2, true]], `${id}: the extra heal on the now full unit`);
assert.deepEqual(got, [3, 3], `${id}: 攫升 for the main heal and for the extra heal that restored nothing`);
checkInvariants(h.b);
}
});
+19 -11
View File
@@ -118,7 +118,7 @@ test('“小自在”: arts melee blocker, 25 s lifetime, kills emit summonKill
checkInvariants(h.b);
});
test('斯卡蒂的海嗣: heals allies in its range; during the owner skill: true dmg/s + 鼓舞; expires, then redeploys after respawnTime', REAL, () => {
test('斯卡蒂的海嗣: its owner\'s trait (生命回复速度) on the allies in its range; during the owner skill: true dmg/s + 鼓舞; expires, then redeploys after respawnTime', REAL, () => {
const bb = tokDef(TOKEN_IDS.seaborn, 'chess_char_6_04_a').skill.bb;
const ratio = tokDef(TOKEN_IDS.seaborn, 'chess_char_6_04_a').traitBb['attack@atk_to_hp_recovery_ratio'];
// heal mode (owner skill idle)
@@ -130,8 +130,13 @@ test('斯卡蒂的海嗣: heals allies in its range; during the owner skill: tru
g.hp = 1000;
const sea = spawnOn(h, sk, TOKEN_IDS.seaborn, 10, 7);
assert.equal(sea.s.flags.untargetable, true);
h.run(3.05);
approx(g.hp - 1000, 3 * sk.s.atk * ratio, 1e-6, 'heal 3 pulses');
h.run(1.05);
// an hpRegen buff keyed by the owner (one trait effect per ally — professions.js bardRegen), refreshed every second
const v = sk.s.atk * ratio;
approx(g.findBuff(`trait:bard:${sk.id}`)?.mods.hpRegen ?? 0, v, 1e-6, 'the owner\'s trait');
const hp0 = g.hp, t1 = h.b.time;
h.run(2);
assert.ok(Math.abs(g.hp - hp0 - v * (h.b.time - t1)) <= 1.5, `regenerated ${g.hp - hp0}`);
const life = tokDef(TOKEN_IDS.seaborn, 'chess_char_6_04_a').talents[0].bb.duration;
h.runUntil(() => !sea.alive, life + 2);
approx(sea.deathAt - sea.deployedAt, life, 0.01, 'lifetime');
@@ -263,14 +268,14 @@ test('hand-authored summoner kits: the board 狼群 deploys before 伺夜 (one p
assert.equal(packs.length, 1, 'a single pack');
assert.equal(packs[0].uid, 2, 'the player\'s piece');
assert.equal(vigil.trait.reinforcement, packs[0]);
// a summoner with a hand kit (no skill here): the seaborn does not run its own heal pulses
// a summoner with a hand kit (no skill here): the seaborn does not run its own trait pulses
const h2 = makeBattle({ defs: { chess: { test_guard: guard() } }, kits: { chess_char_6_04_a: bare }, units: [{ chessId: 'chess_char_6_04_a', row: 12, col: 3 }, { chessId: 'test_guard', row: 10, col: 8 }], autoFinish: false, timeLimit: 30 });
h2.step();
const g = h2.unit('test_guard');
g.hp = 1000;
const sea = spawnOn(h2, h2.unit('chess_char_6_04_a'), TOKEN_IDS.seaborn, 10, 7);
h2.run(3);
assert.equal(g.hp, 1000, 'managed: no token-side heal');
assert.equal(g.hp, 1000, 'managed: no token-side trait');
assert.equal(sea.mem.expiresAt, undefined, 'managed: lifetime left to the owner kit');
checkInvariants(h.b);
});
@@ -495,7 +500,7 @@ test('炎佑: spawnYanyou — flying ally, bond stats, 3 targets with burn + ele
checkInvariants(h.b);
});
test('band map characters: spawnMapChar puts 预备干员-医疗 at its stage slot; Touch 恳切福音 heals ×heal_scale on ≤50 % HP allies', REAL, () => {
test('band map characters: spawnMapChar puts 预备干员-医疗 at its stage slot; Touch 恳切福音 heals ×heal_scale on allies below 50 % HP', REAL, () => {
const g = guard({ stats: { maxHp: 10000 } });
const h = makeBattle({ stageId: 'act2autochess_m01', defs: { chess: { test_guard: g } }, units: [{ chessId: 'test_guard', row: 10, col: 3 }], autoFinish: false, timeLimit: 60,
setup: (b) => b.on('heal', (c) => { if (c.source?.defId === TOKEN_IDS.touch) (b.mem ??= []).push({ amount: c.amount, ratio: c.target.hpRatio, active: c.source.skill.active }); }, { priority: -500 }) });
@@ -515,7 +520,7 @@ test('band map characters: spawnMapChar puts 预备干员-医疗 at its stage sl
gu.hp = 3000;
h.run(4);
const bb = touch.skill.bb;
const low = h.b.mem.find((x) => x.active && x.ratio <= bb.hp_ratio);
const low = h.b.mem.find((x) => x.active && x.ratio < bb.hp_ratio);
assert.ok(low, 'healed a low ally');
approx(low.amount, touch.s.atk * bb.heal_scale, 1e-6, 'boosted heal');
checkInvariants(h.b);
@@ -1090,7 +1095,7 @@ test('预备干员-医疗: stat talent 攻击提升 (+4 % ATK) on top of the dat
approx(med.s.atk, tokDef(TOKEN_IDS.reserveMedic).stats.atk * (1.04 + 0.5), 1e-9, '治疗强化·β型 +50 %');
});
test('Touch talents: 攫升 +3 SP to the healed unit, 超脱 +5 SP when an operator in range is knocked out; extra heal = 30 % of the main heal', REAL, () => {
test('Touch talents: 攫升 +3 SP to the healed unit, 超脱 +5 SP when an operator in range is knocked out; extra heal = 30 % of the main heal\'s base, ×heal_scale on its own low recipient', REAL, () => {
const g = chessRec({ id: 'test_sp', stats: { maxHp: 10000, atk: 0, spRecovery: 0 }, skill: { spCost: 100, initSp: 0 } });
const h = makeBattle({ stageId: 'act2autochess_m01', defs: { chess: { test_sp: g } }, units: [{ chessId: 'test_sp', row: 10, col: 3, uid: 1 }, { chessId: 'test_sp', row: 11, col: 3, uid: 2 }], autoFinish: false, timeLimit: 60,
setup: (b) => b.on('heal', (c) => { if (c.source?.defId === TOKEN_IDS.touch) (b.mem ??= []).push({ t: c.target.id, amount: c.amount, ratio: c.target.hpRatio }); }, { priority: -500 }) });
@@ -1105,14 +1110,17 @@ test('Touch talents: 攫升 +3 SP to the healed unit, 超脱 +5 SP when an opera
h.b.dealDamage(null, b2, { amount: 1e6, type: 'true' });
assert.equal(b2.alive, false);
approx(touch.skill.sp - sp0, 5, 0.1, '超脱');
// skill: main heal (×1.5 at ≤ 50 %) + extra 30 % of it, not boosted again
// skill: main heal (×1.5 below 50 %) + an extra heal of 30 % of its base (ATK) on the lowest-ratio unit of the target and
// its neighbours — the target again, still below half after the main heal: ×1.5 on its own (PRTS 技能3 备注)
h.b.mem = [];
touch.skill.activate('test', { free: true });
a.hp = 4000;
a.hp = 2000;
assert.ok(h.runUntil(() => h.b.mem.length >= 2, 5));
const [main, extra] = h.b.mem;
assert.deepEqual([main.t, extra.t], [a.id, a.id]);
approx(main.amount, touch.s.atk * 1.5, 1e-6, 'main heal boosted');
approx(extra.amount, main.amount * 0.3, 1e-6, 'extra = 30 % of the main heal');
assert.ok(extra.ratio < 0.5);
approx(extra.amount, touch.s.atk * 0.3 * 1.5, 1e-6, 'extra = 30 % of the base, boosted on its low recipient');
checkInvariants(h.b);
});
+111 -111
View File
@@ -139,16 +139,16 @@
"bossHpLeft": null,
"rngDraws": 1,
"errors": {"count":0,"kinds":[]},
"players": {"p1":{"killed":8,"total":8,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":129773,"bossDmg":0,"heal":7530,"deaths":0,"layerGains":{}}},
"players": {"p1":{"killed":8,"total":8,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":129773,"bossDmg":0,"heal":7536,"deaths":0,"layerGains":{}}},
"units": [
["p1",1,"op","chess_char_4_11_b",1,"uniequip_002_cathy",2644,1,5,0,0,0,0,0,0],
["p1",2,"op","chess_char_4_12_b",2,"uniequip_002_glady",2232,1,6,0,14088,0,0,8,1],
["p1",3,"op","chess_char_1_06_b",1,"uniequip_002_vendla",1044.45,1,7,4,47025,6060,2478,45,3],
["p1",3,"op","chess_char_1_06_b",1,"uniequip_002_vendla",1051.4,1,7,4,47025,6060,5773,45,3],
["p1",4,"op","chess_char_1_13_b",1,"uniequip_002_podego",815.5,1,9,1,36853,0,0,38,5],
["p1",5,"op","chess_char_2_14_b",1,"uniequip_002_flower",1544,1,10,0,0,160,4465,22,2],
["p1",6,"op","chess_char_1_06_a",1,null,1137,1,11,1,21655,1572,587,40,1],
["p1",5,"op","chess_char_2_14_b",1,"uniequip_002_flower",1544,1,10,0,0,160,506,22,2],
["p1",6,"op","chess_char_1_06_a",1,null,1137,1,11,1,21655,1572,1226,40,1],
["p1",7,"op","chess_char_1_13_a",1,null,913,1,4,0,870,0,0,1,1],
["p1",8,"op","chess_char_4_10_b",1,"uniequip_002_aroma",1664,1,8,1,9282,95,0,7,2],
["p1",8,"op","chess_char_4_10_b",1,"uniequip_002_aroma",1664,1,8,1,9282,95,31,7,2],
["p1",9,"token","token_10041_cathy_catsld",null,null,100,1,12,0,0,0,0,0,null],
["p1",10,"token","token_10041_cathy_catsld",null,null,100,1,13,0,0,0,0,0,null],
["-","~1","device","trap_1105_accrate",null,null,100,1,1,0,0,0,0,0,null],
@@ -156,10 +156,10 @@
["-","~3","device","trap_1105_accrate",null,null,100,1,3,0,0,0,0,0,null]
],
"enemies": {"enemy_1005_yokai_2":[4,4,0,96,5357],"enemy_1005_yokai_3":[2,2,0,1022,69120],"enemy_9009_acfort":[2,2,0,709,55296]},
"hooks": [1,21,3059,230,230,369,369,234,8,8,15,12,0,11504,115,0,8,0,1,7,0,0,0],
"events": {"atk":230,"deploy":10,"die":8,"dmg":369,"fx":37,"heal":205,"skill":27,"spawn":21,"status":84},
"hooks": [1,21,3059,230,230,369,369,2366,8,8,15,12,0,11504,115,0,8,0,1,7,0,0,0],
"events": {"atk":230,"deploy":10,"die":8,"dmg":369,"fx":37,"heal":78,"skill":27,"spawn":21,"status":84},
"fx": {"beam":2,"counter":16,"pull":1,"slippery":2,"taunt":4,"tornado":1,"tornadoPulse":5,"zone":6},
"snaps": "f7c1fb30 f778388d 11849b13 7f8feebb 1cf8e108 fe9861c9 f8b5d1a0 8331d55b 5e3c8779 87f00fe0 a72ffac2"
"snaps": "f7c1fb30 eb023e29 d1fffc22 c886d0aa 5bf78694 5f3df034 3d54c073 581471d0 d97ecde2 8c045b67 57772151"
},
"bond-egirShip-low": {
"about": "阿戈尔 low: tier 1 layers 1; chess_char_1_04_a chess_char_3_16_a chess_char_2_07_a chess_char_3_18_a chess_char_3_05_a chess_char_3_14_a chess_char_3_17_a chess_char_3_19_a token_10028_vigil_wolf",
@@ -266,22 +266,22 @@
"bossHpLeft": null,
"rngDraws": 68,
"errors": {"count":0,"kinds":[]},
"players": {"p1":{"killed":17,"total":17,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":90450,"bossDmg":0,"heal":396,"deaths":2,"layerGains":{}}},
"players": {"p1":{"killed":17,"total":17,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":90450,"bossDmg":0,"heal":388,"deaths":2,"layerGains":{}}},
"units": [
["p1",1,"op","chess_char_4_01_a",2,null,2638,1,4,0,1888,0,0,18,0],
["p1",2,"op","chess_char_4_04_a",1,null,1760,1,6,1,13660,150,0,30,2],
["p1",3,"op","chess_char_2_14_a",1,null,1232,1,1,0,0,0,396,1,1],
["p1",3,"op","chess_char_2_14_a",1,null,1232,1,1,0,0,0,150,1,1],
["p1",4,"op","chess_char_3_10_a",1,null,1650,1,2,0,0,0,0,0,0],
["p1",5,"op","chess_char_3_20_a",1,null,1121,1,3,0,4312,0,0,22,1],
["p1",6,"op","chess_char_3_21_a",2,null,0,0,7,5,28151,1448,0,36,1],
["p1",6,"op","chess_char_3_21_a",2,null,0,0,7,5,28151,1448,84,36,1],
["p1",7,"op","chess_char_4_02_a",2,null,1428,1,5,7,29406,0,0,18,1],
["p1",8,"op","chess_char_4_06_a",1,null,0,0,8,4,13033,1407,0,33,1]
["p1",8,"op","chess_char_4_06_a",1,null,0,0,8,4,13033,1401,155,33,1]
],
"enemies": {"enemy_10042_prtrop":[4,4,0,2100,21600],"enemy_10042_prtrop_2":[2,2,0,422,14400],"enemy_10043_sailor":[11,11,0,484,54450]},
"hooks": [1,25,1945,179,179,261,261,33,19,19,7,5,0,7219,13,10,17,0,1,19,0,0,0],
"events": {"atk":215,"deploy":8,"die":19,"dmg":260,"fx":32,"heal":33,"skill":12,"spawn":25,"status":44},
"enemies": {"enemy_10042_prtrop":[4,4,0,2093,21600],"enemy_10042_prtrop_2":[2,2,0,421,14400],"enemy_10043_sailor":[11,11,0,484,54450]},
"hooks": [1,25,1945,179,179,261,261,234,19,19,7,5,0,7219,13,10,17,0,1,19,0,0,0],
"events": {"atk":215,"deploy":8,"die":19,"dmg":260,"fx":32,"heal":1,"skill":12,"spawn":25,"status":44},
"fx": {"crit":5,"displace":8,"ripple":7,"shadowWeave":7,"shield":2,"shieldBreak":1,"stealth":2},
"snaps": "190730ef 965c573a 981ee6c8 65f2128e 60bc0584 76df79a4 66b7a509"
"snaps": "190730ef 965c573a bfec9b7d 015e7710 d6c7785b 1a172028 577310dd"
},
"bond-emptyShip-high": {
"about": "协防干员 high: tier 1 layers 999; chess_char_4_17_b chess_char_4_18_b chess_char_4_19_b chess_char_4_22_b chess_char_2_14_b chess_char_3_10_b chess_char_4_20_b chess_char_4_21_b",
@@ -301,24 +301,24 @@
"bossHpLeft": null,
"rngDraws": 63,
"errors": {"count":0,"kinds":[]},
"players": {"p1":{"killed":12,"total":13,"perfect":false,"leaks":1,"leaksUncounted":0,"coins":0,"dmg":214288,"bossDmg":0,"heal":6451,"deaths":1,"layerGains":{}}},
"players": {"p1":{"killed":12,"total":13,"perfect":false,"leaks":1,"leaksUncounted":0,"coins":0,"dmg":214288,"bossDmg":0,"heal":6820,"deaths":1,"layerGains":{}}},
"units": [
["p1",1,"op","chess_char_4_17_b",1,"uniequip_002_hsguma",3513,1,6,0,2200,2954,0,48,0],
["p1",2,"op","chess_char_4_18_b",1,"uniequip_002_mudrok",5573.29,1,7,2,66140,2792,2261,25,7],
["p1",1,"op","chess_char_4_17_b",1,"uniequip_002_hsguma",3513,1,6,0,2200,2954,579,48,0],
["p1",2,"op","chess_char_4_18_b",1,"uniequip_002_mudrok",5957.7,1,7,2,66140,2792,2645,25,7],
["p1",3,"op","chess_char_4_19_b",2,"uniequip_002_flamtl",2118,1,5,0,503,0,0,9,1],
["p1",4,"op","chess_char_4_22_b",2,"uniequip_002_svrash",0,0,8,3,66989,3805,0,77,2],
["p1",5,"op","chess_char_2_14_b",1,"uniequip_002_flower",1544,1,3,0,0,0,4190,16,2],
["p1",4,"op","chess_char_4_22_b",2,"uniequip_002_svrash",0,0,8,3,66989,3790,1221,77,2],
["p1",5,"op","chess_char_2_14_b",1,"uniequip_002_flower",1544,1,3,0,0,0,2375,16,2],
["p1",6,"op","chess_char_3_10_b",1,"uniequip_002_pinecn",2120,1,4,7,56622,0,0,55,4],
["p1",7,"op","chess_char_4_20_b",2,"uniequip_002_fartth",1419,1,9,0,21835,0,0,27,0],
["p1",8,"op","chess_char_4_21_b",1,"uniequip_002_plosis",1584,1,10,0,0,0,0,0,0],
["-","~1","device","trap_1105_accrate",null,null,100,1,1,0,0,0,0,0,null],
["-","~2","device","trap_1105_accrate",null,null,100,1,2,0,0,0,0,0,null]
],
"enemies": {"enemy_1045_hammer_2":[2,1,1,8567,38604],"enemy_1061_zomshd":[11,11,0,983,179484]},
"hooks": [1,23,4184,327,327,641,632,8015,13,14,16,15,0,6375,15,29,13,1,1,15,0,0,2],
"events": {"atk":422,"deploy":8,"die":13,"dmg":622,"fx":104,"heal":76,"leak":1,"skill":31,"spawn":23,"status":44},
"enemies": {"enemy_1045_hammer_2":[2,1,1,8552,38604],"enemy_1061_zomshd":[11,11,0,983,179484]},
"hooks": [1,23,4184,327,327,641,632,9770,13,14,16,15,0,6375,15,29,13,1,1,15,0,0,2],
"events": {"atk":422,"deploy":8,"die":13,"dmg":622,"fx":104,"heal":22,"leak":1,"skill":31,"spawn":23,"status":44},
"fx": {"block":7,"dodge":2,"flame":1,"garrisonGrant":1,"riposte":1,"rockslide":7,"shieldBreak":10,"slash":40,"thorns":33,"truesilver":2},
"snaps": "48d2a0bc 7a5c72a3 804d5560 8c6ca634 c9bf651b 26081476 486ac1ff 38cf6fca b2923b0d 2fd10a7f 9f35ec20 cc9d42df d992cbc0 09a4c858"
"snaps": "48d2a0bc 7a5c72a3 37963453 9c6110e3 fcf46ff8 04b08d2c c03bf731 3792e3d9 e4639ebf decf37ce a41ea7f2 bd40f194 8e5c993d 300fcece"
},
"bond-indomShip-low": {
"about": "不屈 low: tier 1 layers 1; chess_char_1_20_a chess_char_4_11_a chess_char_4_12_a chess_char_2_12_a chess_char_4_09_a chess_char_4_10_a chess_char_4_13_a chess_char_4_14_a token_10041_cathy_catsld token_10041_cathy_catsld",
@@ -378,24 +378,24 @@
"total": 22,
"unspawned": 0,
"bossHpLeft": null,
"rngDraws": 299,
"rngDraws": 298,
"errors": {"count":0,"kinds":[]},
"players": {"p1":{"killed":14,"total":22,"perfect":false,"leaks":8,"leaksUncounted":0,"coins":0,"dmg":263498,"bossDmg":0,"heal":69427,"deaths":20,"layerGains":{}}},
"players": {"p1":{"killed":14,"total":22,"perfect":false,"leaks":8,"leaksUncounted":0,"coins":0,"dmg":263129,"bossDmg":0,"heal":70003,"deaths":19,"layerGains":{}}},
"units": [
["p1",1,"op","chess_char_1_20_b",1,"uniequip_002_liskam",2892,1,50,2,37051,31400,0,95,6],
["p1",2,"op","chess_char_3_16_b",1,"uniequip_002_snakek",2987.31,1,5,0,0,0,0,0,0],
["p1",1,"op","chess_char_1_20_b",1,"uniequip_002_liskam",61.47,1,48,2,37022,31443,7160,94,6],
["p1",2,"op","chess_char_3_16_b",1,"uniequip_002_snakek",3100,1,5,0,0,0,2643,0,0],
["p1",3,"op","chess_char_4_23_b",2,"uniequip_002_gvial2",2811,1,7,0,0,0,0,0,0],
["p1",4,"op","chess_char_5_01_b",1,"uniequip_002_excu2",423.76,1,43,8,145703,33989,15901,154,8],
["p1",5,"op","chess_char_2_12_b",1,"uniequip_002_gravel",1904.37,1,42,1,15616,31855,0,196,0],
["p1",6,"op","chess_char_4_24_b",1,"uniequip_002_billro",2178,1,49,3,65128,4333,172,64,4],
["p1",7,"op","chess_char_4_25_b",2,"uniequip_002_cetsyr",1671,1,47,0,0,7103,34403,0,2],
["p1",8,"op","chess_char_4_26_b",0,"uniequip_002_bldsk",1522,1,46,0,0,11651,18951,34,4]
["p1",5,"op","chess_char_2_12_b",1,"uniequip_002_gravel",1929.76,1,42,1,15616,31872,9053,196,0],
["p1",6,"op","chess_char_4_24_b",1,"uniequip_002_billro",2178,1,49,3,64788,4346,4371,63,4],
["p1",7,"op","chess_char_4_25_b",2,"uniequip_002_cetsyr",1671,1,47,0,0,7103,6480,0,2],
["p1",8,"op","chess_char_4_26_b",0,"uniequip_002_bldsk",1522,1,46,0,0,11712,24394,34,4]
],
"enemies": {"enemy_1166_dusbr_2":[14,12,2,28157,144069],"enemy_1170_dushld_2":[4,2,2,45909,73715],"enemy_9011_acrefr":[4,0,2,46265,45714]},
"hooks": [1,50,5700,833,833,1192,1171,382,34,40,24,26,81,4003,211,60,22,6,1,34,0,0,21],
"events": {"atk":1226,"deploy":28,"die":34,"dmg":1168,"fx":164,"heal":353,"leak":6,"skill":47,"spawn":30,"status":543},
"fx": {"bandage":4,"dodge":21,"extraAttack":42,"garrisonGrant":1,"mote":39,"redistribute":30,"revive":17,"reweave":2,"sandChains":4,"shield":4},
"snaps": "bcca108c 58ad920b bbf7027a 2b945c18 dc91804a 008b26e3 cd75becd c3107a45 7a8b798c 0f3dbb0f e2ba5ade 34847497 7f065901 79837eeb 58f4e601 0b2a0461 1bafcde2 6b8a0480 d949aaa7"
"enemies": {"enemy_1166_dusbr_2":[14,12,2,28217,144069],"enemy_1170_dushld_2":[4,2,2,45909,73715],"enemy_9011_acrefr":[4,0,2,46339,45345]},
"hooks": [1,49,5700,831,831,1190,1169,4295,33,39,24,26,81,4034,210,59,22,6,1,33,0,0,21],
"events": {"atk":1224,"deploy":27,"die":33,"dmg":1166,"fx":163,"heal":167,"leak":6,"skill":47,"spawn":30,"status":541},
"fx": {"bandage":4,"dodge":21,"extraAttack":42,"garrisonGrant":1,"mote":39,"redistribute":30,"revive":16,"reweave":2,"sandChains":4,"shield":4},
"snaps": "bcca108c b78f4774 704b4447 e8becbbe 55de3ed6 7a40bda1 9e89e327 6796cf0f 31697842 2e290595 675d935c 576bc3f1 49c78987 a3206632 6bd55a9d e6a7dcae 9f209030 137f71a3 4b456e75"
},
"bond-investShip-low": {
"about": "投资人 low: tier 1 layers 1; chess_char_4_17_a chess_char_4_18_a chess_char_5_14_a chess_char_4_19_a chess_char_3_04_a chess_char_4_16_a chess_char_2_19_a chess_char_4_20_a",
@@ -507,26 +507,26 @@
"rngDraws": 0,
"errors": {"count":0,"kinds":[]},
"players": {
"p1": {"killed":16,"total":16,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":121696,"bossDmg":0,"heal":13385,"deaths":2,"layerGains":{"kazimierzShip":1}}
"p1": {"killed":16,"total":16,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":121696,"bossDmg":0,"heal":13487,"deaths":2,"layerGains":{"kazimierzShip":1}}
},
"units": [
["p1",1,"op","chess_char_2_18_a",0,null,2218,1,7,8,47314,206,0,23,1],
["p1",2,"op","chess_char_4_23_a",2,null,2179,1,6,0,0,0,0,0,0],
["p1",3,"op","chess_char_4_22_a",2,null,2022,1,8,4,26393,0,0,19,1],
["p1",4,"op","chess_char_1_19_a",1,null,0,0,9,0,15666,5205,0,37,1],
["p1",5,"op","chess_char_2_12_a",1,null,0,0,10,1,24825,7505,0,59,0],
["p1",6,"op","chess_char_4_21_a",1,null,1271,1,4,0,0,0,6519,35,1],
["p1",7,"op","chess_char_4_24_a",1,null,1726,1,5,3,7497,0,0,12,2],
["p1",8,"op","chess_char_4_25_a",2,null,167.6,1,11,0,0,4598,6866,0,1],
["p1",4,"op","chess_char_1_19_a",1,null,0,0,9,0,15120,4341,0,35,1],
["p1",5,"op","chess_char_2_12_a",1,null,0,0,10,1,24825,8504,3348,59,0],
["p1",6,"op","chess_char_4_21_a",1,null,1271,1,4,0,0,0,5770,35,1],
["p1",7,"op","chess_char_4_24_a",1,null,1726,1,5,3,8044,0,0,12,2],
["p1",8,"op","chess_char_4_25_a",2,null,140.06,1,11,0,0,4598,4369,0,1],
["-","~1","device","trap_1105_accrate",null,null,100,1,1,0,0,0,0,0,null],
["-","~2","device","trap_1105_accrate",null,null,100,1,2,0,0,0,0,0,null],
["-","~3","device","trap_1105_accrate",null,null,100,1,3,0,0,0,0,0,null]
],
"enemies": {"enemy_1116_liprr":[11,11,0,4898,69696],"enemy_1116_liprr_2":[4,4,0,179,34560],"enemy_1121_lifbos":[1,1,0,8404,23040]},
"hooks": [1,27,2084,244,244,386,386,119,18,18,7,7,0,7568,12,17,16,0,1,18,1,0,0],
"events": {"atk":264,"deploy":8,"die":18,"dmg":378,"fx":59,"heal":117,"layer":1,"skill":13,"spawn":27,"status":49},
"enemies": {"enemy_1116_liprr":[11,11,0,4898,69696],"enemy_1116_liprr_2":[4,4,0,179,34560],"enemy_1121_lifbos":[1,1,0,8539,23040]},
"hooks": [1,27,2084,242,242,384,384,1800,18,18,7,7,0,7493,12,17,16,0,1,18,1,0,0],
"events": {"atk":265,"deploy":8,"die":18,"dmg":376,"fx":59,"heal":48,"layer":1,"skill":13,"spawn":27,"status":49},
"fx": {"displace":16,"garrison":1,"healField":1,"liberate":4,"redistribute":15,"reweave":1,"sandChains":2,"shield":1,"slash":17,"truesilver":1},
"snaps": "a6ab2e4e 341ce9e0 1a995842 4d0721dc d7bf07b4 399a65a1 faf8bc70"
"snaps": "0bfff00d 05c25821 afccda40 f76042f7 01a83e51 376ea44f e7830c09"
},
"bond-kazimierzShip-high": {
"about": "卡西米尔 high: tier 2 layers 999; chess_char_2_18_b chess_char_3_12_b chess_char_5_08_b chess_char_4_19_b chess_char_1_19_b chess_char_2_12_b chess_char_3_17_b chess_char_5_10_b",
@@ -546,24 +546,24 @@
"bossHpLeft": null,
"rngDraws": 19,
"errors": {"count":0,"kinds":[]},
"players": {"p1":{"killed":30,"total":30,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":403989,"bossDmg":0,"heal":1899,"deaths":3,"layerGains":{}}},
"players": {"p1":{"killed":30,"total":30,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":403989,"bossDmg":0,"heal":1893,"deaths":3,"layerGains":{}}},
"units": [
["p1",1,"op","chess_char_2_18_b",0,"uniequip_002_ashlok",1062.9,1,3,8,95498,2092,0,20,2],
["p1",2,"op","chess_char_3_12_b",2,"uniequip_002_blemsh",3096,1,5,0,0,0,0,0,0],
["p1",3,"op","chess_char_5_08_b",2,"uniequip_002_horn",611.2,1,7,10,69588,4063,0,52,2],
["p1",3,"op","chess_char_5_08_b",2,"uniequip_002_horn",605.79,1,7,10,69588,4063,1893,52,2],
["p1",4,"op","chess_char_4_19_b",2,"uniequip_002_flamtl",2118,1,8,0,20635,0,0,16,2],
["p1",5,"op","chess_char_1_19_b",1,"uniequip_002_wildmn",0,0,9,3,85930,1971,0,51,2],
["p1",6,"op","chess_char_2_12_b",1,"uniequip_002_gravel",0,0,37,2,45298,4646,0,40,0],
["p1",7,"op","chess_char_3_17_b",1,"uniequip_002_shotst",3441.6,1,4,7,84143,0,0,29,3],
["p1",8,"op","chess_char_5_10_b",2,"uniequip_002_lisa",1480,1,6,0,2897,0,1899,10,2],
["p1",8,"op","chess_char_5_10_b",2,"uniequip_002_lisa",1480,1,6,0,2897,0,0,10,2],
["-","~1","device","trap_1105_accrate",null,null,100,1,1,0,0,0,0,0,null],
["-","~2","device","trap_1105_accrate",null,null,100,1,2,0,0,0,0,0,null]
],
"enemies": {"enemy_10124_uashld_2":[2,2,0,4508,124416],"enemy_1043_zomsbr":[23,23,0,20,147057],"enemy_1061_zomshd":[5,5,0,4181,132516]},
"hooks": [1,41,2585,237,237,430,545,2736,33,33,13,13,0,5133,998,10,30,0,1,46,0,0,5],
"events": {"atk":237,"deploy":9,"die":33,"dmg":425,"fx":55,"heal":29,"skill":24,"spawn":40,"status":123},
"hooks": [1,41,2585,237,237,430,545,3521,33,33,13,13,0,5133,998,10,30,0,1,46,0,0,5],
"events": {"atk":237,"deploy":9,"die":33,"dmg":425,"fx":55,"skill":24,"spawn":40,"status":123},
"fx": {"aoe":25,"displace":15,"dodge":5,"flame":2,"overload":2,"riposte":1,"shield":2,"volley":3},
"snaps": "8c049284 5f56b990 54685fa8 8bb93fef ee98b956 2c23e816 2eb3723d b0c9da39 17ae9cf4"
"snaps": "8c049284 94ec5278 5b651787 1fd27218 f0da3e8f e10280c8 9a24dc65 cc785d71 f60edecd"
},
"bond-kjeragShip-low": {
"about": "谢拉格 low: tier 1 layers 1; chess_char_1_02_a chess_char_3_02_a chess_char_3_03_a chess_char_3_04_a chess_char_2_05_a chess_char_3_11_a chess_char_4_26_a chess_char_3_01_a",
@@ -964,14 +964,14 @@
"round": 5,
"seed": 806507299,
"waveId": "act1autochess_05",
"time": 55.83,
"ticks": 1675,
"time": 50.23,
"ticks": 1507,
"reason": "cleared",
"killed": 17,
"total": 17,
"unspawned": 0,
"bossHpLeft": null,
"rngDraws": 9,
"rngDraws": 21,
"errors": {"count":0,"kinds":[]},
"players": {
"p1": {
@@ -983,28 +983,28 @@
"coins": 0,
"dmg": 126144,
"bossDmg": 0,
"heal": 2283,
"deaths": 3,
"layerGains": {"preciShip":4,"raidShip":3}
"heal": 2669,
"deaths": 0,
"layerGains": {"preciShip":4,"raidShip":1}
}
},
"units": [
["p1",1,"op","chess_char_4_17_a",1,null,2849,1,3,1,236,0,0,1,0],
["p1",2,"op","chess_char_4_18_a",1,null,4288.04,1,5,2,4315,483,183,6,2],
["p1",3,"op","chess_char_2_09_a",1,null,0,0,13,6,51195,2479,400,29,1],
["p1",4,"op","chess_char_4_19_a",2,null,0,0,9,0,6131,1560,0,21,1],
["p1",5,"op","chess_char_1_18_a",1,null,0,0,10,0,20642,4230,1700,34,0],
["p1",6,"op","chess_char_4_13_a",1,null,1587,1,4,2,10656,0,0,18,6],
["p1",7,"op","chess_char_4_14_a",1,null,1276,1,6,2,13435,0,0,11,3],
["p1",8,"op","chess_char_4_20_a",2,null,1217,1,8,4,19533,0,0,17,0],
["p1",1,"op","chess_char_4_17_a",1,null,2849,1,3,0,0,0,0,0,0],
["p1",2,"op","chess_char_4_18_a",1,null,4587.2,1,5,1,10682,19,19,12,2],
["p1",3,"op","chess_char_2_09_a",1,null,2047.24,1,17,3,21927,0,0,26,1],
["p1",4,"op","chess_char_4_19_a",2,null,1195.44,1,9,2,23164,365,0,30,1],
["p1",5,"op","chess_char_1_18_a",1,null,1706.55,1,32,7,45410,7067,2650,53,0],
["p1",6,"op","chess_char_4_13_a",1,null,1587,1,4,0,7729,0,0,12,4],
["p1",7,"op","chess_char_4_14_a",1,null,1276,1,6,0,0,0,0,0,0],
["p1",8,"op","chess_char_4_20_a",2,null,1217,1,8,4,17232,0,0,16,0],
["-","~1","device","trap_1105_accrate",null,null,100,1,1,0,0,0,0,0,null],
["-","~2","device","trap_1105_accrate",null,null,100,1,2,0,0,0,0,0,null]
],
"enemies": {"enemy_1116_liprr":[11,11,0,27,69696],"enemy_1116_liprr_2":[4,4,0,324,34560],"enemy_1118_lidbox_2":[2,2,0,7137,21888]},
"hooks": [1,28,1675,191,191,258,256,69,20,21,13,14,0,5765,261,15,17,0,1,20,4,0,3],
"events": {"atk":245,"deploy":9,"die":21,"dmg":228,"fx":34,"heal":39,"layer":4,"skill":26,"spawn":27,"status":74},
"fx": {"aoe":1,"blink":1,"dodge":3,"explosion":3,"flame":1,"frostNova":6,"garrison":4,"garrisonGrant":1,"liberate":5,"riposte":3,"rockslide":2,"shieldBreak":4},
"snaps": "cc3198c7 52e7bc12 2cb83233 e0fed9c4 ccb6b9ae d5efc9c5"
"enemies": {"enemy_1116_liprr":[11,11,0,350,69696],"enemy_1116_liprr_2":[4,4,0,757,34560],"enemy_1118_lidbox_2":[2,2,0,19,21888]},
"hooks": [1,32,1507,195,195,229,226,85,17,22,8,11,0,4625,227,18,17,0,1,17,2,0,8],
"events": {"atk":208,"deploy":13,"die":22,"dmg":211,"fx":42,"heal":54,"layer":2,"skill":15,"spawn":27,"status":65},
"fx": {"aoe":5,"blink":5,"dodge":8,"flame":1,"frostNova":4,"garrison":2,"garrisonGrant":1,"liberate":2,"riposte":8,"rockslide":2,"shieldBreak":4},
"snaps": "c2c19547 f7f121f8 342b4210 25ce41d3 2fc3e7fa"
},
"bond-raidShip-high": {
"about": "突袭 high: tier 1 layers 999; chess_char_4_17_b chess_char_4_18_b chess_char_2_09_b chess_char_4_19_b chess_char_1_18_b chess_char_4_14_b chess_char_4_20_b chess_char_4_21_b",
@@ -1015,8 +1015,8 @@
"round": 10,
"seed": 3301807152,
"waveId": "act1autochess_h03",
"time": 63.7,
"ticks": 1911,
"time": 61.43,
"ticks": 1843,
"reason": "cleared",
"killed": 24,
"total": 24,
@@ -1025,26 +1025,26 @@
"rngDraws": 0,
"errors": {"count":0,"kinds":[]},
"players": {
"p1": {"killed":24,"total":24,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":508861,"bossDmg":0,"heal":4370,"deaths":0,"layerGains":{"preciShip":8}}
"p1": {"killed":24,"total":24,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":508861,"bossDmg":0,"heal":4200,"deaths":0,"layerGains":{"preciShip":8}}
},
"units": [
["p1",1,"op","chess_char_4_17_b",1,"uniequip_002_hsguma",3513,1,4,0,0,0,0,0,0],
["p1",2,"op","chess_char_4_18_b",1,"uniequip_002_mudrok",6104,1,5,0,0,0,0,0,0],
["p1",3,"op","chess_char_2_09_b",1,"uniequip_002_humus",19662.2,1,14,17,316017,6932,2620,42,2],
["p1",3,"op","chess_char_2_09_b",1,"uniequip_002_humus",23974.92,1,46,4,98103,0,0,15,2],
["p1",4,"op","chess_char_4_19_b",2,"uniequip_002_flamtl",2118,1,10,0,0,0,0,0,0],
["p1",5,"op","chess_char_1_18_b",1,"uniequip_002_utage",18074.87,1,31,6,165912,7700,1750,25,0],
["p1",6,"op","chess_char_4_14_b",1,"uniequip_002_lionhd",1626,1,6,1,5126,0,0,1,3],
["p1",7,"op","chess_char_4_20_b",2,"uniequip_002_fartth",1419,1,7,0,21807,0,0,16,0],
["p1",5,"op","chess_char_1_18_b",1,"uniequip_002_utage",18169.4,1,40,20,404123,21798,4200,60,0],
["p1",6,"op","chess_char_4_14_b",1,"uniequip_002_lionhd",1626,1,6,0,0,0,0,0,0],
["p1",7,"op","chess_char_4_20_b",2,"uniequip_002_fartth",1419,1,7,0,6635,0,0,6,0],
["p1",8,"op","chess_char_4_21_b",1,"uniequip_002_plosis",1584,1,9,0,0,0,0,0,0],
["-","~1","device","trap_1105_accrate",null,null,100,1,1,0,0,0,0,0,null],
["-","~2","device","trap_1105_accrate",null,null,100,1,2,0,0,0,0,0,null],
["-","~3","device","trap_1105_accrate",null,null,100,1,3,0,0,0,0,0,null]
],
"enemies": {"enemy_1010_demon":[7,7,0,3616,130637],"enemy_1422_lrsldr_2":[14,14,0,259,191601],"enemy_1425_lrcmra_2":[3,3,0,5726,186624]},
"hooks": [1,38,1911,98,98,109,112,67,24,27,5,6,0,2340,0,14,24,0,1,24,1,0,0],
"events": {"atk":106,"deploy":11,"die":27,"dmg":111,"fx":11,"heal":61,"layer":1,"skill":9,"spawn":35,"status":14},
"fx": {"aoe":3,"blink":3,"explosion":3,"garrison":1,"garrisonGrant":1},
"snaps": "e36eae91 cfb528ed e6a3d2c8 e0f51763 d04dbb08 273b64f9 09b4046d"
"enemies": {"enemy_1010_demon":[7,7,0,2359,130637],"enemy_1422_lrsldr_2":[14,14,0,0,191601],"enemy_1425_lrcmra_2":[3,3,0,2669,186624]},
"hooks": [1,46,1843,96,96,97,107,75,24,35,2,10,0,1717,0,16,24,0,1,24,1,0,0],
"events": {"atk":98,"deploy":19,"die":35,"dmg":101,"fx":23,"heal":60,"layer":1,"skill":3,"spawn":35,"status":27},
"fx": {"aoe":10,"blink":11,"garrison":1,"garrisonGrant":1},
"snaps": "2edb5682 ac7f24ca 074fdc6d 19a401d3 da20371c 72e9aa89 fabecb2b"
},
"bond-sargonShip-low": {
"about": "萨尔贡 low: tier 1 layers 1; chess_char_2_08_a chess_char_1_12_a chess_char_4_22_a chess_char_2_06_a chess_char_4_21_a chess_char_4_25_a chess_char_4_26_a chess_char_3_01_a",
@@ -1065,23 +1065,23 @@
"rngDraws": 2,
"errors": {"count":0,"kinds":[]},
"players": {
"p1": {"killed":15,"total":17,"perfect":false,"leaks":2,"leaksUncounted":0,"coins":0,"dmg":70415,"bossDmg":0,"heal":16918,"deaths":0,"layerGains":{"sargonShip":5}}
"p1": {"killed":15,"total":17,"perfect":false,"leaks":2,"leaksUncounted":0,"coins":0,"dmg":70415,"bossDmg":0,"heal":16874,"deaths":0,"layerGains":{"sargonShip":5}}
},
"units": [
["p1",1,"op","chess_char_2_08_a",1,null,2444.13,1,2,2,2745,6009,0,34,1],
["p1",2,"op","chess_char_1_12_a",1,null,1840,1,1,0,0,0,0,0,0],
["p1",3,"op","chess_char_4_22_a",2,null,2022,1,3,3,30743,1058,0,23,1],
["p1",4,"op","chess_char_2_06_a",0,null,1440,1,4,0,0,927,6893,32,15],
["p1",5,"op","chess_char_4_21_a",1,null,1271,1,7,0,0,2018,4815,42,1],
["p1",6,"op","chess_char_4_25_a",2,null,1221,1,5,0,0,2171,4733,0,1],
["p1",7,"op","chess_char_4_26_a",0,null,1368,1,8,0,0,3301,478,14,0],
["p1",8,"op","chess_char_3_01_a",2,null,1471.8,1,6,10,36927,1620,0,51,1]
["p1",1,"op","chess_char_2_08_a",1,null,2445.15,1,2,2,2745,5992,2167,34,1],
["p1",2,"op","chess_char_1_12_a",1,null,1840,1,1,0,0,0,49,0,0],
["p1",3,"op","chess_char_4_22_a",2,null,2022,1,3,3,30743,1227,726,23,1],
["p1",4,"op","chess_char_2_06_a",0,null,1440,1,4,0,0,1045,7241,31,15],
["p1",5,"op","chess_char_4_21_a",1,null,1271,1,7,0,0,1984,3685,40,1],
["p1",6,"op","chess_char_4_25_a",2,null,1221,1,5,0,0,2019,566,0,1],
["p1",7,"op","chess_char_4_26_a",0,null,1368,1,8,0,0,3189,1939,13,0],
["p1",8,"op","chess_char_3_01_a",2,null,1471.8,1,6,10,36927,1603,501,51,1]
],
"enemies": {"enemy_1267_nhpbr":[11,10,0,4196,43172],"enemy_1267_nhpbr_2":[5,5,0,1614,24750],"enemy_1272_nhtank":[1,0,0,11294,2493]},
"hooks": [1,25,3300,239,239,525,525,340,15,15,20,20,0,14437,0,5,17,0,1,15,1,0,0],
"events": {"atk":353,"deploy":8,"die":15,"dmg":486,"fx":112,"heal":340,"layer":1,"skill":40,"spawn":25,"status":247},
"enemies": {"enemy_1267_nhpbr":[11,10,0,4389,43172],"enemy_1267_nhpbr_2":[5,5,0,1428,24750],"enemy_1272_nhtank":[1,0,0,11242,2493]},
"hooks": [1,25,3300,235,235,525,525,2310,15,15,20,20,0,14437,0,5,17,0,1,15,1,0,0],
"events": {"atk":327,"deploy":8,"die":15,"dmg":484,"fx":112,"heal":166,"layer":1,"skill":40,"spawn":25,"status":237},
"fx": {"buff":1,"counter":15,"garrison":1,"healField":1,"mote":38,"redistribute":15,"reweave":1,"slash":17,"spGift":1,"truesilver":1,"zone":21},
"snaps": "0bdd9351 b24b323e bd7fa0e6 615fd5bb 96279ddc 312fee2e 95a7061f c670e7a9 527b3b7b e067f8d0 97894695"
"snaps": "0bdd9351 b24b323e bd7fa0e6 9082ff11 2ec2d408 d77ed103 82e40b03 8f2326cd 3ebba6a7 7ce5233b e938b951"
},
"bond-sargonShip-high": {
"about": "萨尔贡 high: tier 2 layers 999; chess_char_1_12_b chess_char_2_08_b chess_char_3_06_b chess_char_4_23_b chess_char_4_22_b chess_char_2_06_b chess_char_3_13_b chess_char_4_25_b",
@@ -1103,20 +1103,20 @@
"errors": {"count":0,"kinds":[]},
"players": {"p1":{"killed":30,"total":30,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":261251,"bossDmg":0,"heal":2449,"deaths":2,"layerGains":{}}},
"units": [
["p1",1,"op","chess_char_1_12_b",1,"uniequip_002_estell",3725.8,1,2,0,0,0,0,0,0],
["p1",2,"op","chess_char_2_08_b",1,"uniequip_002_bubble",4709.8,1,3,0,0,0,0,0,0],
["p1",3,"op","chess_char_3_06_b",1,"uniequip_002_philae",5606.8,1,4,1,25073,2355,0,4,1],
["p1",1,"op","chess_char_1_12_b",1,"uniequip_002_estell",3725.8,1,2,0,0,0,195,0,0],
["p1",2,"op","chess_char_2_08_b",1,"uniequip_002_bubble",4709.8,1,3,0,0,0,246,0,0],
["p1",3,"op","chess_char_3_06_b",1,"uniequip_002_philae",5606.8,1,4,1,25073,2355,1920,4,1],
["p1",4,"op","chess_char_4_23_b",2,"uniequip_002_gvial2",0,0,5,15,152408,2811,0,90,1],
["p1",5,"op","chess_char_4_22_b",2,"uniequip_002_svrash",2569,1,39,14,46565,2569,0,29,1],
["p1",6,"op","chess_char_2_06_b",0,"uniequip_002_papyrs",1639,1,7,0,0,0,0,0,0],
["p1",7,"op","chess_char_3_13_b",1,"uniequip_002_malist",1375,1,8,0,37205,0,0,45,11],
["p1",8,"op","chess_char_4_25_b",2,"uniequip_002_cetsyr",1671,1,1,0,0,0,2449,0,2]
["p1",8,"op","chess_char_4_25_b",2,"uniequip_002_cetsyr",1671,1,1,0,0,0,87,0,2]
],
"enemies": {"enemy_1006_shield_3":[3,3,0,5125,138240],"enemy_1043_zomsbr":[23,23,0,48,70867],"enemy_1402_tgshd_2":[4,4,0,1710,59904]},
"hooks": [1,39,3442,191,191,497,653,1788,32,32,16,14,0,6394,0,15,30,0,1,46,0,1,0],
"events": {"atk":225,"deploy":9,"die":32,"dmg":653,"fx":138,"heal":13,"skill":30,"spawn":38,"status":56},
"hooks": [1,39,3442,191,191,497,653,1967,32,32,16,14,0,6394,0,15,30,0,1,46,0,1,0],
"events": {"atk":225,"deploy":9,"die":32,"dmg":653,"fx":138,"skill":30,"spawn":38,"status":56},
"fx": {"aoe":5,"burst":1,"expose":63,"jungleSoul":1,"mote":20,"redistribute":25,"reweave":2,"slash":20,"truesilver":1},
"snaps": "2c6321b4 cd26a52a 90107827 1e040533 bf55c7a2 587efe24 04e3a230 2316a1be 704aab56 56e8ca2f 9b645a1a 7f429b8f"
"snaps": "2c6321b4 cd26a52a 90107827 1e040533 bf55c7a2 587efe24 04e3a230 2316a1be 704aab56 d4f428ad 361a7d9c 9efe2d19"
},
"bond-siracusaShip-low": {
"about": "叙拉古 low: tier 1 layers 1; chess_char_3_06_a chess_char_1_08_a chess_char_2_16_a chess_char_3_02_a chess_char_3_03_a chess_char_3_04_a chess_char_3_05_a chess_char_1_07_a",
@@ -1248,22 +1248,22 @@
"bossHpLeft": null,
"rngDraws": 0,
"errors": {"count":0,"kinds":[]},
"players": {"p1":{"killed":18,"total":18,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":236160,"bossDmg":0,"heal":1795,"deaths":1,"layerGains":{}}},
"players": {"p1":{"killed":18,"total":18,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":236160,"bossDmg":0,"heal":1855,"deaths":1,"layerGains":{}}},
"units": [
["p1",1,"op","chess_char_5_08_b",2,"uniequip_002_horn",743.7,1,3,1,6396,2031,0,6,1],
["p1",2,"op","chess_char_5_05_b",2,"uniequip_002_ulpia",9448,1,6,0,8643,0,0,0,2],
["p1",3,"op","chess_char_5_07_b",2,"uniequip_002_surtr",1,0,8,5,61017,9474,0,19,1],
["p1",3,"op","chess_char_5_07_b",2,"uniequip_002_surtr",1,0,8,5,61017,9534,1855,19,1],
["p1",4,"op","chess_char_1_14_b",1,"uniequip_002_greyy",0,0,1,0,0,1505,0,0,0],
["p1",5,"op","chess_char_2_04_b",1,"uniequip_002_grabds",889,1,4,1,3923,0,0,5,1],
["p1",6,"op","chess_char_5_02_b",2,"uniequip_002_titi",1439,1,5,11,148521,0,0,112,2],
["p1",7,"op","chess_char_5_03_b",2,"uniequip_002_blaze2",1472,1,2,0,0,0,0,0,0],
["p1",8,"op","chess_char_5_10_b",2,"uniequip_002_lisa",1480,1,7,0,7660,0,1795,12,2]
["p1",8,"op","chess_char_5_10_b",2,"uniequip_002_lisa",1480,1,7,0,7660,0,0,12,2]
],
"enemies": {"enemy_1116_liprr_2":[10,10,0,0,86400],"enemy_1119_vofsd":[5,5,0,0,63360],"enemy_1121_lifbos_2":[3,3,0,0,86400]},
"hooks": [1,26,2220,154,154,260,495,28,19,20,9,6,0,4772,242,0,18,0,1,65,0,0,0],
"events": {"atk":158,"deploy":8,"die":20,"dmg":260,"fx":11,"heal":27,"skill":15,"spawn":26,"status":109},
"hooks": [1,26,2220,154,154,260,495,800,19,20,9,6,0,4772,242,0,18,0,1,65,0,0,0],
"events": {"atk":158,"deploy":8,"die":20,"dmg":260,"fx":11,"skill":15,"spawn":26,"status":109},
"fx": {"anchor":2,"aoe":1,"ember":1,"overload":1,"sleep":1,"wake":5},
"snaps": "64e99ee5 1abd1f62 a61568a8 f70d6ada 147d6954 2222525f 19319fc6 a63f0cc1"
"snaps": "a670acd9 9001d709 b6201c30 2abbe338 097e73f6 82d908fd d1618a08 83c56b8b"
},
"bond-soloShip-low": {
"about": "独行 low: tier 1 layers 1; chess_char_3_16_a chess_char_4_01_a chess_char_1_08_a chess_char_3_18_a chess_char_3_19_a chess_char_3_20_a chess_char_3_21_a chess_char_4_02_a token_10028_vigil_wolf",
+309 -310
View File
File diff suppressed because it is too large. Load diff
+100 -100
View File
@@ -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":14,"hiddenReached":false,"hiddenCleared":false,"reason":"victory","teamLp":10,"bossPoolLeft":0,"virtualMs":106900},
"end": {"victory":true,"roundsPassed":14,"hiddenReached":false,"hiddenCleared":false,"reason":"victory","teamLp":11,"bossPoolLeft":0,"virtualMs":106900},
"rng": {"setup":25,"shop":207,"waves":0,"draft":10,"bots":8483,"meta":14},
"errors": {"engine":0,"logged":0,"sim":0,"dispatcher":0},
"rounds": [
@@ -118,27 +118,27 @@
},
{
"round": 8,
"ai_0": [1,20,11,0,0,4,8,"9642d3a4",62,"deputShip 1/6, emptyShip 1/2, kazimierzShip 0/8, kjeragShip 1/9, preciShip 0/5, sargonShip 0/8, siracusaShip 1/31, soloShip 1/14, steadShip 0/6, swiftShip 0/8",12,19,7,60]
"ai_0": [1,21,11,0,0,4,8,"9642d3a4",62,"deputShip 1/6, emptyShip 1/2, kazimierzShip 0/8, kjeragShip 1/9, preciShip 0/5, sargonShip 0/8, siracusaShip 1/31, soloShip 1/14, steadShip 0/6, swiftShip 0/8",13,19,6,60]
},
{
"round": 9,
"ai_0": [1,20,12,0,0,4,8,"765a4a23",99,"arcaneShip 0/2, deputShip 1/8, emptyShip 1/4, kazimierzShip 0/8, kjeragShip 0/14, preciShip 0/12, sargonShip 0/8, siracusaShip 1/53, soloShip 1/16, steadShip 0/6, suntShip 1/2, swiftShip 1/16",18,18,0,73]
"ai_0": [1,21,12,0,0,4,8,"765a4a23",99,"arcaneShip 0/2, deputShip 1/8, emptyShip 1/4, kazimierzShip 0/8, kjeragShip 0/14, preciShip 0/12, sargonShip 0/8, siracusaShip 1/53, soloShip 1/16, steadShip 0/6, suntShip 1/2, swiftShip 1/16",18,18,0,73]
},
{
"round": 10,
"ai_0": [1,20,12,0,0,5,8,"44e95a01",112,"arcaneShip 0/2, deputShip 0/8, emptyShip 0/4, kazimierzShip 0/8, kjeragShip 0/14, miraShip 1/3, preciShip 0/12, sargonShip 0/8, siracusaShip 2/69, soloShip 1/16, steadShip 0/6, suntShip 1/2, swiftShip 1/22",24,24,0,87]
"ai_0": [1,21,12,0,0,5,8,"44e95a01",112,"arcaneShip 0/2, deputShip 0/8, emptyShip 0/4, kazimierzShip 0/8, kjeragShip 0/14, miraShip 1/3, preciShip 0/12, sargonShip 0/8, siracusaShip 2/69, soloShip 1/16, steadShip 0/6, suntShip 1/2, swiftShip 1/22",24,24,0,87]
},
{
"round": 11,
"ai_0": [1,20,12,0,0,5,8,"12000646",141,"arcaneShip 0/2, deputShip 0/8, emptyShip 0/4, kazimierzShip 0/8, kjeragShip 0/14, miraShip 1/6, preciShip 0/12, sargonShip 0/8, siracusaShip 2/95, soloShip 1/16, steadShip 0/6, suntShip 1/2, swiftShip 1/22",24,24,0,98]
"ai_0": [1,21,12,0,0,5,8,"12000646",141,"arcaneShip 0/2, deputShip 0/8, emptyShip 0/4, kazimierzShip 0/8, kjeragShip 0/14, miraShip 1/6, preciShip 0/12, sargonShip 0/8, siracusaShip 2/95, soloShip 1/16, steadShip 0/6, suntShip 1/2, swiftShip 1/22",24,24,0,98]
},
{
"round": 12,
"ai_0": [1,10,12,0,0,6,8,"03cea672",154,"arcaneShip 0/2, deputShip 0/8, emptyShip 0/4, kazimierzShip 0/8, kjeragShip 0/14, miraShip 1/9, preciShip 0/12, sargonShip 0/8, siracusaShip 2/105, soloShip 1/16, steadShip 0/6, suntShip 1/2, swiftShip 1/22",17,31,14,109]
"ai_0": [1,11,12,0,0,6,8,"03cea672",154,"arcaneShip 0/2, deputShip 0/8, emptyShip 0/4, kazimierzShip 0/8, kjeragShip 0/14, miraShip 1/9, preciShip 0/12, sargonShip 0/8, siracusaShip 2/105, soloShip 1/16, steadShip 0/6, suntShip 1/2, swiftShip 1/22",18,31,13,109]
},
{
"round": 13,
"ai_0": [1,10,12,0,0,6,8,"1cf42739",230,"arcaneShip 0/2, deputShip 2/12, emptyShip 1/8, kazimierzShip 0/16, kjeragShip 0/22, miraShip 1/13, preciShip 0/12, sargonShip 0/8, siracusaShip 1/129, soloShip 1/20, steadShip 0/6, suntShip 1/6, swiftShip 1/42",115,115,0,121]
"ai_0": [1,11,12,0,0,6,8,"1cf42739",230,"arcaneShip 0/2, deputShip 2/12, emptyShip 1/8, kazimierzShip 0/16, kjeragShip 0/22, miraShip 1/13, preciShip 0/12, sargonShip 0/8, siracusaShip 1/129, soloShip 1/20, steadShip 0/6, suntShip 1/6, swiftShip 1/42",115,115,0,121]
}
],
"players": {
@@ -147,12 +147,12 @@
"victory": true,
"roundsPassed": 14,
"eliminatedRound": null,
"lp": 10,
"lp": 11,
"bandId": "band_ermengard",
"title": {"id":"comment_1","name":"卫戍之星","picId":"comment_icon_1","text":"对敌方领袖造成伤害最高(仅胜利时)"},
"trophies": 0,
"reward": 400,
"stats": {"activatedLayers":290,"bossDamage":97500,"dmgDealt":1691540,"gold":131,"itemsEquipped":23,"kills":361,"leaks":21,"lpLost":17,"merges":5,"perfectRounds":11,"refreshes":15},
"stats": {"activatedLayers":290,"bossDamage":97500,"dmgDealt":1718251,"gold":131,"itemsEquipped":23,"kills":362,"leaks":19,"lpLost":16,"merges":5,"perfectRounds":11,"refreshes":15},
"lineup": ["2_14_a@12,5","5_10_a@12,7[4_07_e_a+3_08_e_b]","5_20_b@11,5[6_09_e_a+5_02_e_b]","3_20_b@11,8[3_06_e_a+4_08_e_a]","6_11_a@10,3[4_12_e_a+5_02_e_b]","3_18_a@10,8[2_04_e_b+4_05_e_b]","6_19_a@9,4[4_04_e_a+4_10_e_a]","1_08_a@9,5[1_01_e_a+1_02_e_a]"],
"bonds": ["arcaneShip 0/2","deputShip 1/14","emptyShip 1/10","kazimierzShip 0/16","kjeragShip 1/24","maniShip 1/2","miraShip 1/15","preciShip 0/12","sargonShip 0/8","siracusaShip 1/151","soloShip 1/22","steadShip 0/6","suntShip 1/8","swiftShip 1/44"]
}
@@ -243,8 +243,8 @@
"combat": "client",
"boost": null,
"setup": {"stageId":"act1autochess_m03","bossId":"boss_5","hiddenBossId":"boss_8","factions":["TIMES","DOT","INVISIBLE"]},
"end": {"victory":true,"roundsPassed":14,"hiddenReached":false,"hiddenCleared":false,"reason":"victory","teamLp":9,"bossPoolLeft":0,"virtualMs":107800},
"rng": {"setup":25,"shop":201,"waves":0,"draft":42,"bots":8376,"meta":2},
"end": {"victory":true,"roundsPassed":14,"hiddenReached":false,"hiddenCleared":false,"reason":"victory","teamLp":10,"bossPoolLeft":0,"virtualMs":107800},
"rng": {"setup":25,"shop":208,"waves":0,"draft":42,"bots":8380,"meta":2},
"errors": {"engine":0,"logged":0,"sim":0,"dispatcher":0},
"rounds": [
{"round":1,"ai_0":[1,27,4,0,0,1,2,"cc1bac8f",0,"sargonShip 0/2, soloShip 1/0",5,5,0,4]},
@@ -262,27 +262,27 @@
},
{
"round": 8,
"ai_0": [1,24,11,0,0,4,8,"6960d5f9",68,"deputShip 1/6, emptyShip 1/2, kazimierzShip 0/8, kjeragShip 1/9, preciShip 0/5, sargonShip 0/8, siracusaShip 1/29, soloShip 1/7, steadShip 1/15, swiftShip 0/8",16,19,3,61]
"ai_0": [1,27,11,0,0,4,8,"e874f996",70,"deputShip 1/6, emptyShip 1/2, kazimierzShip 0/8, kjeragShip 1/9, preciShip 0/5, sargonShip 0/8, siracusaShip 1/31, soloShip 1/7, steadShip 1/15, swiftShip 0/8",19,19,0,61]
},
{
"round": 9,
"ai_0": [1,24,12,0,0,4,8,"ee973cc6",104,"arcaneShip 1/10, deputShip 1/8, emptyShip 1/4, kazimierzShip 0/8, kjeragShip 1/16, preciShip 1/14, sargonShip 0/8, siracusaShip 1/43, soloShip 1/9, steadShip 0/15, swiftShip 0/8",34,34,0,75]
"ai_0": [1,27,12,0,0,4,8,"ce7f2146",106,"arcaneShip 1/10, deputShip 1/8, emptyShip 1/4, kazimierzShip 0/8, kjeragShip 1/16, preciShip 1/14, sargonShip 0/8, siracusaShip 1/45, soloShip 1/9, steadShip 0/15, swiftShip 0/8",34,34,0,75]
},
{
"round": 10,
"ai_0": [1,24,12,0,0,5,8,"b4c89cd7",130,"arcaneShip 1/12, deputShip 1/10, emptyShip 1/6, kazimierzShip 0/8, kjeragShip 1/23, preciShip 1/21, sargonShip 0/8, siracusaShip 1/47, soloShip 1/11, steadShip 0/15, swiftShip 0/8",24,24,0,86]
"ai_0": [1,27,12,0,0,5,8,"d54ffbc1",122,"arcaneShip 1/12, deputShip 1/10, emptyShip 1/6, kazimierzShip 0/8, kjeragShip 1/18, preciShip 1/16, sargonShip 0/8, siracusaShip 1/49, soloShip 1/11, steadShip 0/15, swiftShip 0/8",24,24,0,86]
},
{
"round": 11,
"ai_0": [1,19,12,0,2,5,8,"1d52aad9",174,"arcaneShip 1/20, deputShip 1/12, emptyShip 1/8, kazimierzShip 0/8, kjeragShip 1/32, preciShip 1/28, sargonShip 0/8, siracusaShip 1/61, soloShip 1/13, steadShip 0/17, swiftShip 0/8",29,34,5,97]
"ai_0": [1,22,12,0,0,5,8,"ab08ec3d",166,"arcaneShip 1/20, deputShip 1/12, emptyShip 1/8, kazimierzShip 0/8, kjeragShip 1/27, preciShip 1/23, sargonShip 0/8, siracusaShip 1/63, soloShip 1/13, steadShip 0/17, swiftShip 0/8",29,34,5,97]
},
{
"round": 12,
"ai_0": [1,9,14,0,0,6,8,"4dd4e915",198,"arcaneShip 0/20, deputShip 1/14, emptyShip 1/10, kazimierzShip 0/8, kjeragShip 1/39, preciShip 1/40, sargonShip 0/8, siracusaShip 1/65, soloShip 1/15, steadShip 0/17, swiftShip 1/15",9,31,22,111]
"ai_0": [1,12,12,0,0,6,8,"74d6918c",192,"arcaneShip 1/22, deputShip 1/14, emptyShip 1/10, kazimierzShip 0/8, kjeragShip 1/34, preciShip 1/30, sargonShip 0/8, siracusaShip 1/67, soloShip 1/15, steadShip 0/17, swiftShip 0/8",8,31,23,109]
},
{
"round": 13,
"ai_0": [1,9,12,0,2,6,8,"42f17176",232,"arcaneShip 1/26, deputShip 0/14, emptyShip 1/10, kazimierzShip 0/8, kjeragShip 1/39, preciShip 2/45, sargonShip 0/8, siracusaShip 1/77, soloShip 1/15, steadShip 0/17, swiftShip 1/20",115,115,0,126]
"ai_0": [1,12,12,0,2,6,8,"4f518971",204,"arcaneShip 2/28, deputShip 0/14, emptyShip 1/10, kazimierzShip 0/8, kjeragShip 1/39, preciShip 1/35, sargonShip 0/8, siracusaShip 1/77, soloShip 1/15, steadShip 0/17, swiftShip 0/8",115,115,0,122]
}
],
"players": {
@@ -291,14 +291,14 @@
"victory": true,
"roundsPassed": 14,
"eliminatedRound": null,
"lp": 9,
"lp": 10,
"bandId": "band_ermengard",
"title": {"id":"comment_1","name":"卫戍之星","picId":"comment_icon_1","text":"对敌方领袖造成伤害最高(仅胜利时)"},
"trophies": 0,
"reward": 425,
"stats": {"activatedLayers":270,"bossDamage":195000,"dmgDealt":1657417,"gold":140,"itemsEquipped":16,"kills":378,"leaks":30,"lpLost":18,"merges":3,"perfectRounds":10,"refreshes":15},
"lineup": ["6_12_a@12,5[5_01_e_a+5_02_e_a]","5_10_a@12,7[4_07_e_a+5_02_e_b]","4_14_a@11,8","3_11_a@10,3","5_14_a@9,4[3_08_e_a+3_11_e_a]","1_08_a@9,5[1_01_e_a+4_05_e_a]","6_02_a@9,6","4_10_a@9,8[4_08_e_a+4_10_e_b]"],
"bonds": ["arcaneShip 1/30","deputShip 0/14","emptyShip 1/10","kazimierzShip 0/16","kjeragShip 1/51","preciShip 2/50","sargonShip 0/8","siracusaShip 1/81","soloShip 1/15","steadShip 0/21","swiftShip 1/33","visiShip 1/0"]
"stats": {"activatedLayers":193,"bossDamage":195000,"dmgDealt":1688857,"gold":134,"itemsEquipped":14,"kills":381,"leaks":28,"lpLost":15,"merges":3,"perfectRounds":11,"refreshes":16},
"lineup": ["6_12_a@12,5","5_10_a@12,6[4_07_e_a+5_02_e_b]","3_20_b@12,7[3_11_e_a+5_02_e_b]","6_02_a@11,8","6_16_a@10,3","5_14_a@9,4","1_08_a@9,5[4_05_e_a+1_01_e_b]","4_10_a@9,8[4_08_e_a+1_02_e_a]"],
"bonds": ["arcaneShip 2/42","deputShip 0/14","emptyShip 1/10","kazimierzShip 0/8","kjeragShip 1/39","miraShip 1/0","preciShip 0/35","sargonShip 0/8","siracusaShip 1/87","soloShip 1/15","steadShip 0/17","swiftShip 0/8"]
}
}
},
@@ -406,23 +406,23 @@
},
{
"round": 8,
"ai_0": [1,23,11,0,0,4,8,"214665a0",66,"deputShip 1/6, emptyShip 1/2, kazimierzShip 0/8, kjeragShip 1/9, preciShip 0/5, sargonShip 0/8, siracusaShip 1/27, soloShip 1/7, steadShip 1/15, swiftShip 0/8",15,19,4,61]
"ai_0": [1,23,11,0,0,4,8,"214665a0",68,"deputShip 1/6, emptyShip 1/2, kazimierzShip 0/8, kjeragShip 1/9, preciShip 0/5, sargonShip 0/8, siracusaShip 1/29, soloShip 1/7, steadShip 1/15, swiftShip 0/8",15,19,4,61]
},
{
"round": 9,
"ai_0": [1,23,12,0,0,4,8,"5b26e714",102,"arcaneShip 1/10, deputShip 1/8, emptyShip 1/4, kazimierzShip 0/8, kjeragShip 1/16, preciShip 1/14, sargonShip 0/8, siracusaShip 1/41, soloShip 1/9, steadShip 0/15, swiftShip 0/8",34,34,0,75]
"ai_0": [1,23,12,0,0,4,8,"5b26e714",104,"arcaneShip 1/10, deputShip 1/8, emptyShip 1/4, kazimierzShip 0/8, kjeragShip 1/16, preciShip 1/14, sargonShip 0/8, siracusaShip 1/43, soloShip 1/9, steadShip 0/15, swiftShip 0/8",34,34,0,75]
},
{
"round": 10,
"ai_0": [1,13,12,0,0,5,8,"c2aed33a",128,"arcaneShip 1/12, deputShip 1/10, emptyShip 1/6, kazimierzShip 0/8, kjeragShip 1/23, preciShip 1/21, sargonShip 0/8, siracusaShip 1/45, soloShip 1/11, steadShip 0/15, swiftShip 0/8",11,24,13,86]
"ai_0": [1,13,12,0,0,5,8,"c2aed33a",130,"arcaneShip 1/12, deputShip 1/10, emptyShip 1/6, kazimierzShip 0/8, kjeragShip 1/23, preciShip 1/21, sargonShip 0/8, siracusaShip 1/47, soloShip 1/11, steadShip 0/15, swiftShip 0/8",11,24,13,86]
},
{
"round": 11,
"ai_0": [1,3,12,0,0,5,8,"08ebba3b",172,"arcaneShip 1/20, deputShip 1/12, emptyShip 1/8, kazimierzShip 0/8, kjeragShip 1/32, preciShip 1/28, sargonShip 0/8, siracusaShip 1/59, soloShip 1/13, steadShip 0/17, swiftShip 0/8",17,34,17,97]
"ai_0": [1,3,12,0,0,5,8,"08ebba3b",174,"arcaneShip 1/20, deputShip 1/12, emptyShip 1/8, kazimierzShip 0/8, kjeragShip 1/32, preciShip 1/28, sargonShip 0/8, siracusaShip 1/61, soloShip 1/13, steadShip 0/17, swiftShip 0/8",16,34,18,97]
},
{
"round": 12,
"ai_0": [0,0,12,0,0,6,0,"811c9dc5",0,"arcaneShip 0/22, deputShip 0/14, emptyShip 0/10, kazimierzShip 0/8, kjeragShip 0/39, preciShip 0/35, sargonShip 0/8, siracusaShip 0/63, soloShip 0/15, steadShip 0/17, swiftShip 0/8",7,31,24,109]
"ai_0": [0,0,12,0,0,6,0,"811c9dc5",0,"arcaneShip 0/22, deputShip 0/14, emptyShip 0/10, kazimierzShip 0/8, kjeragShip 0/39, preciShip 0/35, sargonShip 0/8, siracusaShip 0/65, soloShip 0/15, steadShip 0/17, swiftShip 0/8",8,31,23,109]
}
],
"players": {
@@ -436,9 +436,9 @@
"title": {"id":"comment_4","name":"精英云集","picId":"comment_icon_4","text":"晋升精锐次数最多"},
"trophies": 0,
"reward": 255,
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":1583711,"gold":109,"itemsEquipped":10,"kills":226,"leaks":58,"lpLost":34,"merges":2,"perfectRounds":8,"refreshes":9},
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":1613113,"gold":109,"itemsEquipped":10,"kills":226,"leaks":58,"lpLost":34,"merges":2,"perfectRounds":8,"refreshes":9},
"lineup": [],
"bonds": ["arcaneShip 0/22","deputShip 0/14","emptyShip 0/10","kazimierzShip 0/8","kjeragShip 0/39","preciShip 0/35","sargonShip 0/8","siracusaShip 0/63","soloShip 0/15","steadShip 0/17","swiftShip 0/8"]
"bonds": ["arcaneShip 0/22","deputShip 0/14","emptyShip 0/10","kazimierzShip 0/8","kjeragShip 0/39","preciShip 0/35","sargonShip 0/8","siracusaShip 0/65","soloShip 0/15","steadShip 0/17","swiftShip 0/8"]
}
}
},
@@ -658,37 +658,37 @@
},
{
"round": 7,
"ai_0": [1,25,10,0,0,4,8,"7dbd16ef",20,"kazimierzShip 1/2, kjeragShip 0/2, raidShip 1/4, skillfulShip 1/3, soloShip 1/3, steadShip 1/6, swiftShip 1/2",28,28,0,51],
"ai_0": [1,25,10,0,0,4,8,"7dbd16ef",18,"kazimierzShip 1/2, kjeragShip 0/2, raidShip 1/3, skillfulShip 1/3, soloShip 1/3, steadShip 1/5, swiftShip 1/2",28,28,0,51],
"ai_1": [1,24,10,0,2,4,8,"b6785496",2,"arcaneShip 0/2, kazimierzShip 0/2, preciShip 0/2, sargonShip 0/4, skillfulShip 1/0, soloShip 1/0, swiftShip 1/2",28,28,0,53]
},
{
"round": 8,
"ai_0": [1,25,11,0,0,4,8,"50b7d162",55,"kazimierzShip 1/16, kjeragShip 0/2, raidShip 1/20, skillfulShip 1/6, soloShip 1/3, steadShip 2/10, swiftShip 0/4",9,9,0,61],
"ai_0": [1,25,11,0,0,4,8,"50b7d162",53,"kazimierzShip 1/16, kjeragShip 0/2, raidShip 1/19, skillfulShip 1/6, soloShip 1/3, steadShip 2/9, swiftShip 0/4",9,9,0,61],
"ai_1": [1,21,13,0,0,4,8,"bdd566ef",15,"arcaneShip 0/2, kazimierzShip 0/2, preciShip 2/15, sargonShip 0/4, siracusaShip 1/0, skillfulShip 1/0, soloShip 1/0, swiftShip 0/2",4,9,5,66]
},
{
"round": 9,
"ai_0": [1,25,12,0,2,4,8,"468d37f7",70,"kazimierzShip 1/19, kjeragShip 0/2, raidShip 1/28, skillfulShip 0/9, soloShip 1/3, steadShip 2/12, suntShip 1/0, swiftShip 1/8",23,23,0,73],
"ai_1": [1,18,12,0,1,4,8,"f01fb873",39,"arcaneShip 0/2, kazimierzShip 0/2, preciShip 1/28, sargonShip 0/4, siracusaShip 1/4, skillfulShip 1/0, soloShip 1/0, swiftShip 1/7",17,23,6,78]
"ai_0": [1,25,12,0,2,4,8,"d4f6e277",70,"kazimierzShip 1/19, kjeragShip 0/2, raidShip 1/30, skillfulShip 0/9, soloShip 1/3, steadShip 2/10, suntShip 1/0, swiftShip 1/8",23,23,0,73],
"ai_1": [1,17,12,0,1,4,8,"f01fb873",39,"arcaneShip 0/2, kazimierzShip 0/2, preciShip 1/28, sargonShip 0/4, siracusaShip 1/4, skillfulShip 1/0, soloShip 1/0, swiftShip 1/7",17,23,6,78]
},
{
"round": 10,
"ai_0": [1,23,14,0,1,5,8,"eb530a8d",82,"kazimierzShip 1/25, kjeragShip 0/2, raidShip 1/28, skillfulShip 0/9, soloShip 1/3, steadShip 2/12, suntShip 1/0, swiftShip 1/14",6,8,2,88],
"ai_1": [1,14,13,0,0,5,8,"ad2dc598",61,"arcaneShip 0/2, kazimierzShip 0/2, preciShip 1/41, sargonShip 0/4, siracusaShip 1/4, skillfulShip 1/2, soloShip 1/0, suntShip 1/0, swiftShip 1/14",4,8,4,91]
"ai_0": [1,23,14,0,1,5,8,"eb530a8d",82,"kazimierzShip 1/25, kjeragShip 0/2, raidShip 1/30, skillfulShip 0/9, soloShip 1/3, steadShip 2/10, suntShip 1/0, swiftShip 1/14",6,8,2,88],
"ai_1": [1,13,13,0,0,5,8,"ad2dc598",61,"arcaneShip 0/2, kazimierzShip 0/2, preciShip 1/41, sargonShip 0/4, siracusaShip 1/4, skillfulShip 1/2, soloShip 1/0, suntShip 1/0, swiftShip 1/14",4,8,4,91]
},
{
"round": 11,
"ai_0": [1,13,13,0,1,5,8,"cf13d02e",107,"kazimierzShip 1/33, kjeragShip 0/2, raidShip 1/33, skillfulShip 0/9, soloShip 1/3, steadShip 2/12, suntShip 1/0, swiftShip 1/26",9,27,18,100],
"ai_1": [1,4,12,0,0,5,8,"66c45cf0",83,"arcaneShip 0/2, kazimierzShip 0/2, preciShip 1/50, sargonShip 0/4, siracusaShip 1/8, skillfulShip 1/4, soloShip 1/0, suntShip 1/0, swiftShip 1/21",6,27,21,102]
"ai_0": [1,13,13,0,1,5,8,"4ab7af95",99,"kazimierzShip 1/29, kjeragShip 0/2, raidShip 1/35, skillfulShip 0/9, soloShip 1/3, steadShip 2/10, suntShip 1/0, swiftShip 1/22",12,27,15,100],
"ai_1": [1,3,12,0,0,5,8,"66c45cf0",83,"arcaneShip 0/2, kazimierzShip 0/2, preciShip 1/50, sargonShip 0/4, siracusaShip 1/8, skillfulShip 1/4, soloShip 1/0, suntShip 1/0, swiftShip 1/21",6,27,21,102]
},
{
"round": 12,
"ai_0": [1,3,13,0,0,6,8,"17862185",123,"kazimierzShip 1/39, kjeragShip 0/2, raidShip 1/34, skillfulShip 0/9, soloShip 1/3, steadShip 2/17, suntShip 1/0, swiftShip 1/30, visiShip 1/0",17,50,33,114],
"ai_0": [1,3,13,0,0,6,8,"b7e09946",119,"kazimierzShip 1/33, kjeragShip 0/2, raidShip 1/42, skillfulShip 0/9, soloShip 1/3, steadShip 2/11, suntShip 1/0, swiftShip 1/30, visiShip 1/0",17,50,33,114],
"ai_1": [0,0,12,0,0,6,0,"811c9dc5",0,"arcaneShip 0/2, kazimierzShip 0/2, preciShip 0/59, sargonShip 0/4, siracusaShip 0/8, skillfulShip 0/6, swiftShip 0/23",19,50,31,114]
},
{
"round": 13,
"ai_0": [0,0,12,0,0,6,0,"811c9dc5",0,"kazimierzShip 0/51, kjeragShip 0/2, miraShip 0/7, preciShip 0/8, raidShip 0/34, skillfulShip 0/9, soloShip 0/3, steadShip 0/17, swiftShip 0/38, yanShip 0/6",14,49,35,126],
"ai_0": [0,0,12,0,0,6,0,"811c9dc5",0,"kazimierzShip 0/45, kjeragShip 0/2, miraShip 0/7, preciShip 0/8, raidShip 0/42, skillfulShip 0/9, soloShip 0/3, steadShip 0/11, swiftShip 0/38, yanShip 0/6",13,49,36,126],
"ai_1": [0,0,0,0,0,6,0,"811c9dc5",0,"arcaneShip 0/2, kazimierzShip 0/2, preciShip 0/59, sargonShip 0/4, siracusaShip 0/8, skillfulShip 0/6, swiftShip 0/23",null,null,null,114]
}
],
@@ -703,9 +703,9 @@
"title": {"id":"comment_4","name":"精英云集","picId":"comment_icon_4","text":"晋升精锐次数最多"},
"trophies": 3,
"reward": 298,
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":2497540,"gold":126,"itemsEquipped":8,"kills":203,"leaks":88,"lpLost":32,"merges":4,"perfectRounds":9,"refreshes":13},
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":2447629,"gold":126,"itemsEquipped":8,"kills":204,"leaks":86,"lpLost":32,"merges":4,"perfectRounds":9,"refreshes":13},
"lineup": [],
"bonds": ["kazimierzShip 0/51","kjeragShip 0/2","miraShip 0/7","preciShip 0/8","raidShip 0/34","skillfulShip 0/9","soloShip 0/3","steadShip 0/17","swiftShip 0/38","yanShip 0/6"]
"bonds": ["kazimierzShip 0/45","kjeragShip 0/2","miraShip 0/7","preciShip 0/8","raidShip 0/42","skillfulShip 0/9","soloShip 0/3","steadShip 0/11","swiftShip 0/38","yanShip 0/6"]
},
"ai_1": {
"alive": false,
@@ -717,7 +717,7 @@
"title": {"id":"comment_5","name":"万事俱备","picId":"comment_icon_5","text":"装备配发数量最多"},
"trophies": 2,
"reward": 255,
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":1355731,"gold":114,"itemsEquipped":11,"kills":160,"leaks":73,"lpLost":32,"merges":3,"perfectRounds":5,"refreshes":19},
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":1355731,"gold":114,"itemsEquipped":11,"kills":160,"leaks":73,"lpLost":33,"merges":3,"perfectRounds":5,"refreshes":19},
"lineup": [],
"bonds": ["arcaneShip 0/2","kazimierzShip 0/2","preciShip 0/59","sargonShip 0/4","siracusaShip 0/8","skillfulShip 0/6","swiftShip 0/23"]
}
@@ -1084,7 +1084,7 @@
},
{
"round": 7,
"ai_0": [1,25,12,0,0,4,8,"81d63726",45,"arcaneShip 0/8, kazimierzShip 1/14, kjeragShip 0/5, preciShip 1/17, suntShip 1/0, swiftShip 1/14",6,21,15,53],
"ai_0": [1,25,12,0,0,4,8,"81d63726",45,"arcaneShip 0/8, kazimierzShip 1/14, kjeragShip 0/5, preciShip 1/17, suntShip 1/0, swiftShip 1/14",4,21,17,53],
"ai_1": [1,4,10,0,0,4,8,"f1d0d89f",38,"arcaneShip 0/2, deputShip 1/2, kazimierzShip 1/15, kjeragShip 0/2, preciShip 0/2, sargonShip 0/4, siracusaShip 0/6, soloShip 1/2, steadShip 0/2, swiftShip 1/19",10,21,11,50],
"ai_2": [1,13,10,0,0,4,8,"1cee0d77",78,"deputShip 1/16, egirShip 0/4, kazimierzShip 0/2, kjeragShip 0/16, raidShip 0/4, soloShip 1/12, steadShip 2/42, swiftShip 1/8, victoriaShip 0/12, yanShip 0/4",20,21,1,51],
"ai_3": [1,3,11,0,0,4,8,"cae1e8d2",28,"arcaneShip 2/7, preciShip 0/2, sargonShip 0/2, siracusaShip 1/15, skillfulShip 1/2, soloShip 1/4",3,21,18,55]
@@ -1129,7 +1129,7 @@
"title": {"id":"comment_4","name":"精英云集","picId":"comment_icon_4","text":"晋升精锐次数最多"},
"trophies": 2,
"reward": 213,
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":1538413,"gold":99,"itemsEquipped":11,"kills":86,"leaks":76,"lpLost":49,"merges":2,"perfectRounds":4,"refreshes":12},
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":1532699,"gold":99,"itemsEquipped":11,"kills":84,"leaks":78,"lpLost":49,"merges":2,"perfectRounds":4,"refreshes":12},
"lineup": [],
"bonds": ["arcaneShip 0/14","kazimierzShip 0/54","kjeragShip 0/15","preciShip 0/42","skillfulShip 0/10","swiftShip 0/19"]
},
@@ -1187,8 +1187,8 @@
"combat": "server",
"boost": null,
"setup": {"stageId":"act1autochess_m01","bossId":"boss_1","hiddenBossId":"boss_9","factions":["FLY","DOT","REFLECTION"]},
"end": {"victory":false,"roundsPassed":12,"hiddenReached":false,"hiddenCleared":false,"reason":"eliminated","teamLp":null,"bossPoolLeft":null,"virtualMs":113300},
"rng": {"setup":25,"shop":389,"waves":0,"draft":34,"bots":16823,"meta":81},
"end": {"victory":true,"roundsPassed":14,"hiddenReached":false,"hiddenCleared":false,"reason":"victory","teamLp":23,"bossPoolLeft":0,"virtualMs":121400},
"rng": {"setup":25,"shop":535,"waves":0,"draft":34,"bots":18101,"meta":103},
"errors": {"engine":0,"logged":0,"sim":0,"dispatcher":0},
"rounds": [
{
@@ -1223,68 +1223,68 @@
},
{
"round": 7,
"ai_0": [1,19,13,0,0,4,8,"bfa893e9",41,"arcaneShip 0/2, kjeragShip 0/2, preciShip 1/2, siracusaShip 1/22, soloShip 1/11, steadShip 0/2, swiftShip 1/6",12,27,15,52],
"ai_0": [1,19,13,0,2,4,8,"bfa893e9",41,"arcaneShip 0/2, kjeragShip 0/2, preciShip 1/2, siracusaShip 1/22, soloShip 1/11, steadShip 0/2, swiftShip 1/6",12,27,15,52],
"ai_1": [1,18,11,0,1,4,8,"eac0b2d5",6,"arcaneShip 0/2, kjeragShip 0/4, preciShip 1/2, siracusaShip 1/0, soloShip 1/0, steadShip 2/4",16,27,11,51]
},
{
"round": 8,
"ai_0": [1,19,11,0,0,4,8,"7c223b06",62,"arcaneShip 1/6, emptyShip 1/0, kjeragShip 0/7, preciShip 1/7, siracusaShip 1/32, soloShip 1/11, steadShip 0/2, swiftShip 1/6",23,23,0,64],
"ai_1": [1,16,12,0,0,4,8,"2243ec88",26,"arcaneShip 1/8, indomShip 1/1, kjeragShip 0/4, preciShip 0/2, siracusaShip 1/10, soloShip 1/0, steadShip 2/7",18,23,5,61]
"ai_0": [1,19,13,0,0,4,8,"15883c96",68,"arcaneShip 1/8, emptyShip 1/0, kjeragShip 0/7, preciShip 1/7, siracusaShip 1/36, soloShip 1/11, steadShip 0/2, swiftShip 1/6",23,23,0,66],
"ai_1": [1,18,12,0,0,4,8,"bf07aea2",44,"arcaneShip 1/8, kjeragShip 0/4, preciShip 2/26, siracusaShip 1/10, soloShip 1/0, steadShip 0/4",23,23,0,62]
},
{
"round": 9,
"ai_0": [1,19,12,0,1,4,8,"6dfc43a6",74,"arcaneShip 2/12, emptyShip 1/0, indomShip 0/8, kjeragShip 0/7, preciShip 1/7, siracusaShip 1/38, soloShip 1/11, steadShip 0/2, suntShip 1/0, swiftShip 1/6, victoriaShip 0/8, visiShip 0/8",16,16,0,77],
"ai_1": [1,16,12,0,0,4,8,"bbe510e7",82,"arcaneShip 1/16, indomShip 1/10, kjeragShip 0/8, preciShip 1/22, siracusaShip 1/20, soloShip 1/0, steadShip 1/14, victoriaShip 0/8, visiShip 0/8",15,15,0,74]
"ai_0": [1,19,12,0,2,4,8,"b4babcf7",91,"arcaneShip 1/14, indomShip 0/8, kjeragShip 0/7, miraShip 1/2, preciShip 0/7, siracusaShip 2/58, soloShip 1/11, steadShip 0/2, suntShip 1/0, swiftShip 1/6, victoriaShip 0/8, visiShip 0/8",16,16,0,79],
"ai_1": [1,18,12,0,2,4,8,"3a24956f",64,"arcaneShip 1/12, indomShip 0/8, kjeragShip 0/4, preciShip 2/34, siracusaShip 1/18, soloShip 1/0, steadShip 0/4, victoriaShip 0/8, visiShip 0/8",15,15,0,76]
},
{
"round": 10,
"ai_0": [1,18,13,0,0,5,8,"e24edc84",78,"arcaneShip 2/14, emptyShip 1/0, indomShip 0/8, kjeragShip 0/7, preciShip 1/7, siracusaShip 1/40, soloShip 1/11, steadShip 0/2, suntShip 1/0, swiftShip 1/6, victoriaShip 0/8, visiShip 0/8",23,24,1,89],
"ai_1": [1,16,12,0,0,5,8,"f2b57087",100,"arcaneShip 1/16, indomShip 1/12, kjeragShip 0/8, miraShip 0/3, preciShip 1/35, siracusaShip 1/20, soloShip 1/0, steadShip 1/17, suntShip 1/0, victoriaShip 0/8, visiShip 0/8, yanShip 0/6",23,23,0,86]
"ai_0": [1,18,14,0,0,5,8,"4991ed8e",108,"arcaneShip 1/16, indomShip 0/8, kjeragShip 0/7, miraShip 1/5, preciShip 0/7, siracusaShip 2/70, soloShip 1/11, steadShip 0/2, suntShip 1/0, swiftShip 1/6, victoriaShip 0/8, visiShip 0/8",23,24,1,93],
"ai_1": [1,17,14,0,0,5,8,"995fa88f",75,"arcaneShip 1/12, emptyShip 1/0, indomShip 0/8, kjeragShip 0/4, preciShip 2/45, siracusaShip 1/18, soloShip 1/0, steadShip 0/4, victoriaShip 0/8, visiShip 0/8",22,23,1,90]
},
{
"round": 11,
"ai_0": [1,9,12,0,0,5,8,"586b372b",90,"arcaneShip 2/20, emptyShip 1/0, indomShip 0/8, kjeragShip 0/7, preciShip 1/7, siracusaShip 1/46, soloShip 1/11, steadShip 0/2, suntShip 1/0, swiftShip 1/6, victoriaShip 0/8, visiShip 0/8",14,23,9,101],
"ai_1": [1,12,12,0,0,5,8,"b5188f04",124,"arcaneShip 2/26, indomShip 1/14, kazimierzShip 0/8, kjeragShip 0/16, miraShip 0/3, preciShip 1/54, siracusaShip 1/30, soloShip 1/0, steadShip 0/17, suntShip 1/0, swiftShip 0/8, victoriaShip 0/8, visiShip 0/8, yanShip 0/6",19,23,4,99]
"ai_0": [1,15,12,0,0,5,8,"4e6b0d40",138,"arcaneShip 1/22, indomShip 0/8, kjeragShip 0/7, miraShip 1/7, preciShip 0/7, siracusaShip 2/92, soloShip 1/11, steadShip 0/2, suntShip 1/0, swiftShip 1/6, victoriaShip 0/8, visiShip 0/8",20,23,3,106],
"ai_1": [1,17,12,0,0,5,8,"c6b4d06f",114,"arcaneShip 1/24, emptyShip 1/0, indomShip 0/8, kjeragShip 0/4, preciShip 2/62, siracusaShip 1/28, soloShip 1/0, steadShip 0/4, victoriaShip 0/8, visiShip 0/8",23,23,0,104]
},
{
"round": 12,
"ai_0": [0,0,12,0,0,5,0,"811c9dc5",0,"arcaneShip 0/24, indomShip 0/8, kjeragShip 0/7, preciShip 0/7, siracusaShip 0/50, soloShip 0/11, steadShip 0/2, swiftShip 0/6, victoriaShip 0/8, visiShip 0/8",27,46,19,114],
"ai_1": [1,2,12,0,0,6,8,"f5a033f5",153,"arcaneShip 2/26, indomShip 0/14, kazimierzShip 0/8, kjeragShip 0/16, miraShip 0/3, preciShip 1/78, siracusaShip 1/30, soloShip 1/0, steadShip 1/19, suntShip 1/0, swiftShip 0/8, victoriaShip 0/8, visiShip 0/8, yanShip 0/6",27,46,19,111]
"ai_0": [1,15,12,0,2,6,8,"ac215c06",147,"arcaneShip 1/22, indomShip 0/8, kjeragShip 0/7, miraShip 1/10, preciShip 0/7, siracusaShip 2/98, soloShip 1/11, steadShip 0/2, suntShip 1/0, swiftShip 1/6, victoriaShip 0/8, visiShip 0/8",33,46,13,118],
"ai_1": [1,17,12,0,0,6,8,"c4e0303a",121,"arcaneShip 1/24, emptyShip 1/0, indomShip 0/8, kjeragShip 0/4, preciShip 2/69, siracusaShip 1/28, soloShip 1/0, steadShip 0/4, victoriaShip 0/8, visiShip 0/8",46,46,0,115]
},
{
"round": 13,
"ai_0": [0,0,0,0,0,5,0,"811c9dc5",0,"arcaneShip 0/24, indomShip 0/8, kjeragShip 0/7, preciShip 0/7, siracusaShip 0/50, soloShip 0/11, steadShip 0/2, swiftShip 0/6, victoriaShip 0/8, visiShip 0/8",null,null,null,114],
"ai_1": [0,0,12,0,0,6,0,"811c9dc5",0,"arcaneShip 0/32, indomShip 0/14, kazimierzShip 0/16, kjeragShip 0/24, miraShip 0/3, preciShip 0/102, siracusaShip 0/42, steadShip 0/19, swiftShip 0/16, victoriaShip 0/8, visiShip 0/8, yanShip 0/6",27,39,12,121]
"ai_0": [1,6,14,0,0,6,8,"953e06bc",186,"arcaneShip 1/31, indomShip 0/8, kjeragShip 0/7, miraShip 1/13, preciShip 0/7, siracusaShip 2/125, soloShip 1/11, steadShip 0/2, suntShip 1/0, swiftShip 1/6, victoriaShip 0/8, visiShip 0/8",30,39,9,132],
"ai_1": [1,17,12,0,0,6,8,"eaf7de57",159,"arcaneShip 2/34, emptyShip 1/0, indomShip 0/8, kjeragShip 0/4, preciShip 2/87, siracusaShip 1/38, soloShip 1/0, steadShip 0/4, victoriaShip 0/8, visiShip 0/8",39,39,0,126]
}
],
"players": {
"ai_0": {
"alive": false,
"victory": false,
"roundsPassed": 11,
"eliminatedRound": 12,
"lp": 0,
"alive": true,
"victory": true,
"roundsPassed": 14,
"eliminatedRound": null,
"lp": 6,
"bandId": "band_doberm",
"title": {"id":"comment_4","name":"精英云集","picId":"comment_icon_4","text":"晋升精锐次数最多"},
"trophies": 2,
"reward": 240,
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":2035070,"gold":114,"itemsEquipped":13,"kills":194,"leaks":45,"lpLost":31,"merges":4,"perfectRounds":7,"refreshes":15},
"lineup": [],
"bonds": ["arcaneShip 0/24","indomShip 0/8","kjeragShip 0/7","preciShip 0/7","siracusaShip 0/50","soloShip 0/11","steadShip 0/2","swiftShip 0/6","victoriaShip 0/8","visiShip 0/8"]
"title": {"id":"comment_1","name":"卫戍之星","picId":"comment_icon_1","text":"对敌方领袖造成伤害最高(仅胜利时)"},
"trophies": 4,
"reward": 400,
"stats": {"activatedLayers":217,"bossDamage":427385,"dmgDealt":3482385,"gold":143,"itemsEquipped":20,"kills":242,"leaks":42,"lpLost":24,"merges":2,"perfectRounds":7,"refreshes":25},
"lineup": ["1_17_a@11,6[1_02_e_a+1_05_e_a]","3_19_a@11,7[3_05_e_b+5_01_e_a]","5_20_a@10,3[3_02_e_a+3_03_e_b]","4_10_a@10,4[4_03_e_a+1_01_e_b]","3_18_a@10,7[6_09_e_a+3_11_e_b]","1_08_b@10,8[4_11_e_a+3_08_e_a]","6_05_a@9,8","4_16_a@9,9"],
"bonds": ["arcaneShip 1/37","indomShip 0/8","kjeragShip 0/7","miraShip 1/13","preciShip 1/7","raidShip 1/0","siracusaShip 2/143","soloShip 1/11","steadShip 0/2","swiftShip 1/6","victoriaShip 0/8","visiShip 0/8"]
},
"ai_1": {
"alive": false,
"victory": false,
"roundsPassed": 12,
"eliminatedRound": 13,
"lp": 0,
"alive": true,
"victory": true,
"roundsPassed": 14,
"eliminatedRound": null,
"lp": 17,
"bandId": "band_malkie",
"title": {"id":"comment_5","name":"万事俱备","picId":"comment_icon_5","text":"装备配发数量最多"},
"trophies": 3,
"reward": 280,
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":2655538,"gold":121,"itemsEquipped":18,"kills":217,"leaks":51,"lpLost":36,"merges":3,"perfectRounds":8,"refreshes":17},
"lineup": [],
"bonds": ["arcaneShip 0/32","indomShip 0/14","kazimierzShip 0/16","kjeragShip 0/24","miraShip 0/3","preciShip 0/102","siracusaShip 0/42","steadShip 0/19","swiftShip 0/16","victoriaShip 0/8","visiShip 0/8","yanShip 0/6"]
"title": {"id":"comment_3","name":"坚若磐石","picId":"comment_icon_3","text":"目标生命值损失最少"},
"trophies": 4,
"reward": 400,
"stats": {"activatedLayers":193,"bossDamage":247615,"dmgDealt":3734549,"gold":138,"itemsEquipped":20,"kills":269,"leaks":12,"lpLost":11,"merges":3,"perfectRounds":11,"refreshes":25},
"lineup": ["4_25_a@12,3","6_12_a@11,6[2_01_e_a+1_05_e_b]","1_17_b@11,7[4_08_e_a+1_01_e_a]","5_02_a@10,3","4_10_a@10,7[3_01_e_b+1_02_e_b]","3_18_a@10,8","5_12_a@9,8[1_05_e_a]","1_08_a@9,9[4_10_e_a+5_07_e_a]"],
"bonds": ["arcaneShip 2/49","emptyShip 1/0","indomShip 0/8","kjeragShip 0/8","preciShip 2/87","siracusaShip 1/57","soloShip 1/0","steadShip 0/8","swiftShip 0/6","victoriaShip 0/8","visiShip 0/8"]
}
}
},
@@ -1493,7 +1493,7 @@
"combat": "client",
"boost": null,
"setup": {"stageId":"act1autochess_m01","bossId":"boss_5","hiddenBossId":"boss_10","factions":["DOT","INVISIBLE","REFLECTION"]},
"end": {"victory":true,"roundsPassed":14,"hiddenReached":false,"hiddenCleared":false,"reason":"victory","teamLp":2,"bossPoolLeft":0,"virtualMs":116550},
"end": {"victory":true,"roundsPassed":14,"hiddenReached":false,"hiddenCleared":false,"reason":"victory","teamLp":5,"bossPoolLeft":0,"virtualMs":115050},
"rng": {"setup":25,"shop":495,"waves":0,"draft":34,"bots":17791,"meta":11},
"errors": {"engine":0,"logged":0,"sim":0,"dispatcher":0},
"rounds": [
@@ -1524,43 +1524,43 @@
},
{
"round": 6,
"h_0": [1,28,9,0,2,3,8,"9b4b0e34",36,"arcaneShip 0/4, kazimierzShip 0/8, preciShip 0/4, raidShip 1/28, soloShip 1/0, swiftShip 1/8, yanShip 0/1",31,31,0,39],
"ai_0": [1,23,9,0,1,3,8,"c6b88ba7",52,"arcaneShip 0/2, deputShip 2/8, kazimierzShip 0/8, lateranoShip 1/15, preciShip 0/10, sargonShip 0/2, suntShip 1/6, swiftShip 1/23",31,31,0,39]
"h_0": [1,28,9,0,2,3,8,"9b4b0e34",32,"arcaneShip 0/4, kazimierzShip 0/8, preciShip 0/4, raidShip 1/24, soloShip 1/0, swiftShip 1/8, yanShip 0/1",31,31,0,39],
"ai_0": [1,23,9,0,1,3,8,"c6b88ba7",55,"arcaneShip 0/2, deputShip 2/8, kazimierzShip 0/8, lateranoShip 1/18, preciShip 0/10, sargonShip 0/2, suntShip 1/6, swiftShip 1/23",31,31,0,39]
},
{
"round": 7,
"h_0": [1,28,12,0,2,4,8,"f09ca8b6",44,"arcaneShip 0/4, kazimierzShip 0/8, preciShip 0/4, raidShip 1/36, soloShip 1/0, swiftShip 1/8, yanShip 0/1",34,34,0,50],
"ai_0": [1,23,11,0,1,4,8,"f6f38045",77,"arcaneShip 0/2, deputShip 2/12, kazimierzShip 0/8, lateranoShip 1/25, preciShip 0/10, sargonShip 0/2, suntShip 1/10, swiftShip 1/30",34,34,0,50]
"ai_0": [1,23,11,0,1,4,8,"f6f38045",80,"arcaneShip 0/2, deputShip 2/12, kazimierzShip 0/8, lateranoShip 1/28, preciShip 0/10, sargonShip 0/2, suntShip 1/10, swiftShip 1/30",34,34,0,50]
},
{
"round": 8,
"h_0": [1,25,13,0,2,4,8,"1070819b",63,"arcaneShip 1/7, kazimierzShip 0/8, preciShip 0/4, raidShip 1/48, skillfulShip 1/0, swiftShip 1/8, yanShip 0/1",12,15,3,62],
"ai_0": [1,23,12,0,0,4,8,"87633ca6",106,"arcaneShip 0/2, deputShip 2/16, kazimierzShip 0/8, lateranoShip 1/35, preciShip 0/10, sargonShip 0/2, skillfulShip 1/4, suntShip 1/14, swiftShip 1/37",15,15,0,62]
"h_0": [1,28,13,0,2,4,8,"2bca9c35",63,"arcaneShip 1/7, kazimierzShip 0/8, preciShip 0/4, raidShip 1/48, skillfulShip 1/0, swiftShip 1/8, yanShip 0/1",15,15,0,62],
"ai_0": [1,23,12,0,0,4,8,"87633ca6",109,"arcaneShip 0/2, deputShip 2/16, kazimierzShip 0/8, lateranoShip 1/41, preciShip 0/10, sargonShip 0/2, skillfulShip 1/4, suntShip 1/14, swiftShip 1/34",15,15,0,62]
},
{
"round": 9,
"h_0": [1,23,14,0,0,4,8,"70a00d2f",50,"arcaneShip 1/10, kazimierzShip 1/12, preciShip 1/9, raidShip 0/48, skillfulShip 1/3, soloShip 1/0, swiftShip 1/16, yanShip 0/1",21,23,2,76],
"ai_0": [1,21,12,0,0,4,8,"8dc0d798",161,"arcaneShip 0/2, deputShip 1/18, kazimierzShip 0/8, lateranoShip 1/47, preciShip 1/20, sargonShip 0/2, skillfulShip 1/11, suntShip 1/16, swiftShip 1/49",21,23,2,75]
"h_0": [1,26,14,0,0,4,8,"70a00d2f",50,"arcaneShip 1/10, kazimierzShip 1/12, preciShip 1/9, raidShip 0/48, skillfulShip 1/3, soloShip 1/0, swiftShip 1/16, yanShip 0/1",21,23,2,76],
"ai_0": [1,22,12,0,0,4,8,"8dc0d798",164,"arcaneShip 0/2, deputShip 1/18, kazimierzShip 0/8, lateranoShip 1/56, preciShip 1/20, sargonShip 0/2, skillfulShip 1/11, suntShip 1/16, swiftShip 1/43",22,23,1,75]
},
{
"round": 10,
"h_0": [1,23,12,0,0,5,8,"59b986b7",73,"arcaneShip 1/10, kazimierzShip 1/19, preciShip 1/14, raidShip 0/48, skillfulShip 1/6, soloShip 1/3, swiftShip 1/21, yanShip 0/1",31,31,0,87],
"ai_0": [1,21,12,0,0,5,8,"fa71d132",188,"arcaneShip 0/2, deputShip 0/18, kazimierzShip 0/8, lateranoShip 1/71, preciShip 1/25, sargonShip 0/2, skillfulShip 1/16, suntShip 1/16, swiftShip 1/60",31,31,0,88]
"h_0": [1,26,12,0,0,5,8,"59b986b7",73,"arcaneShip 1/10, kazimierzShip 1/19, preciShip 1/14, raidShip 0/48, skillfulShip 1/6, soloShip 1/3, swiftShip 1/21, yanShip 0/1",31,31,0,87],
"ai_0": [1,22,12,0,0,5,8,"fa71d132",198,"arcaneShip 0/2, deputShip 0/18, kazimierzShip 0/8, lateranoShip 1/91, preciShip 1/25, sargonShip 0/2, skillfulShip 1/16, suntShip 1/16, swiftShip 1/50",31,31,0,88]
},
{
"round": 11,
"h_0": [1,19,12,0,0,5,8,"b7278144",146,"arcaneShip 0/10, kazimierzShip 1/34, preciShip 2/19, raidShip 1/61, skillfulShip 0/9, soloShip 1/6, suntShip 1/0, swiftShip 1/26, yanShip 0/1",21,25,4,99],
"ai_0": [1,19,12,0,0,5,8,"e240abda",226,"arcaneShip 0/2, deputShip 0/18, kazimierzShip 0/8, lateranoShip 1/79, preciShip 1/33, raidShip 1/5, sargonShip 0/2, skillfulShip 1/21, suntShip 1/16, swiftShip 1/67, visiShip 1/5",23,25,2,100]
"h_0": [1,22,12,0,0,5,8,"b7278144",146,"arcaneShip 0/10, kazimierzShip 1/34, preciShip 2/19, raidShip 1/61, skillfulShip 0/9, soloShip 1/6, suntShip 1/0, swiftShip 1/26, yanShip 0/1",21,25,4,99],
"ai_0": [1,12,12,0,0,5,8,"e240abda",236,"arcaneShip 0/2, deputShip 0/18, kazimierzShip 0/8, lateranoShip 1/99, preciShip 1/33, raidShip 1/5, sargonShip 0/2, skillfulShip 1/21, suntShip 1/16, swiftShip 1/57, visiShip 1/5",14,25,11,100]
},
{
"round": 12,
"h_0": [1,12,12,0,0,6,8,"955db8af",172,"arcaneShip 0/10, kazimierzShip 1/42, preciShip 2/24, raidShip 1/69, skillfulShip 0/9, soloShip 1/6, suntShip 1/0, swiftShip 1/31, yanShip 0/1",24,31,7,111],
"ai_0": [1,9,12,0,2,6,8,"3c27819a",264,"arcaneShip 0/2, deputShip 0/18, kazimierzShip 0/8, lateranoShip 1/87, preciShip 1/41, raidShip 1/10, sargonShip 0/2, skillfulShip 1/26, suntShip 1/16, swiftShip 1/74, visiShip 1/10",17,31,14,113]
"h_0": [1,15,12,0,0,6,8,"955db8af",172,"arcaneShip 0/10, kazimierzShip 1/42, preciShip 2/24, raidShip 1/69, skillfulShip 0/9, soloShip 1/6, suntShip 1/0, swiftShip 1/31, yanShip 0/1",24,31,7,111],
"ai_0": [1,2,12,0,2,6,8,"3c27819a",274,"arcaneShip 0/2, deputShip 0/18, kazimierzShip 0/8, lateranoShip 1/107, preciShip 1/41, raidShip 1/10, sargonShip 0/2, skillfulShip 1/26, suntShip 1/16, swiftShip 1/64, visiShip 1/10",18,31,13,113]
},
{
"round": 13,
"h_0": [1,2,12,0,0,6,8,"1bd1e6d0",244,"arcaneShip 1/10, kazimierzShip 1/54, preciShip 2/34, raidShip 1/105, skillfulShip 0/9, soloShip 0/6, suntShip 1/0, swiftShip 1/41, yanShip 0/1",20,57,37,122],
"ai_0": [0,0,14,0,0,6,0,"811c9dc5",0,"arcaneShip 0/2, deputShip 0/18, kazimierzShip 0/8, lateranoShip 0/95, preciShip 0/49, raidShip 0/15, sargonShip 0/2, skillfulShip 0/31, suntShip 0/16, swiftShip 0/81, visiShip 0/15",15,57,42,126]
"h_0": [1,5,12,0,0,6,8,"1bd1e6d0",244,"arcaneShip 1/10, kazimierzShip 1/54, preciShip 2/34, raidShip 1/105, skillfulShip 0/9, soloShip 0/6, suntShip 1/0, swiftShip 1/41, yanShip 0/1",20,57,37,122],
"ai_0": [0,0,14,0,0,6,0,"811c9dc5",0,"arcaneShip 0/2, deputShip 0/18, kazimierzShip 0/8, lateranoShip 0/115, preciShip 0/49, raidShip 0/15, sargonShip 0/2, skillfulShip 0/31, suntShip 0/16, swiftShip 0/71, visiShip 0/15",15,57,42,126]
}
],
"players": {
@@ -1569,12 +1569,12 @@
"victory": true,
"roundsPassed": 14,
"eliminatedRound": null,
"lp": 2,
"lp": 5,
"bandId": "band_amedic",
"title": {"id":"comment_1","name":"卫戍之星","picId":"comment_icon_1","text":"对敌方领袖造成伤害最高(仅胜利时)"},
"trophies": 4,
"reward": 400,
"stats": {"activatedLayers":276,"bossDamage":390000,"dmgDealt":2811982,"gold":135,"itemsEquipped":23,"kills":254,"leaks":53,"lpLost":26,"merges":5,"perfectRounds":8,"refreshes":21},
"stats": {"activatedLayers":276,"bossDamage":390000,"dmgDealt":2834408,"gold":135,"itemsEquipped":23,"kills":257,"leaks":50,"lpLost":23,"merges":5,"perfectRounds":9,"refreshes":21},
"lineup": ["6_05_a@12,3[3_08_e_a+3_05_e_a]","4_14_b@11,3[3_11_e_b+6_05_e_a]","1_17_b@10,3","6_19_a@10,4","6_17_a@10,7[4_08_e_a+1_05_e_b]","6_06_a@10,8[1_01_e_a+4_04_e_a]","3_12_a@9,4[4_04_e_b+1_02_e_b]","3_13_b@9,8[2_01_e_a+4_03_e_a]"],
"bonds": ["arcaneShip 0/14","kazimierzShip 1/62","kjeragShip 0/8","preciShip 2/48","raidShip 1/105","sargonShip 1/2","skillfulShip 0/9","soloShip 0/6","suntShip 1/0","swiftShip 1/59","yanShip 0/1"]
},
@@ -1588,9 +1588,9 @@
"title": {"id":"comment_6","name":"挥金如土","picId":"comment_icon_6","text":"消耗资金最多"},
"trophies": 3,
"reward": 280,
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":2138966,"gold":126,"itemsEquipped":15,"kills":234,"leaks":60,"lpLost":24,"merges":3,"perfectRounds":9,"refreshes":23},
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":2105193,"gold":126,"itemsEquipped":15,"kills":227,"leaks":67,"lpLost":31,"merges":3,"perfectRounds":9,"refreshes":23},
"lineup": [],
"bonds": ["arcaneShip 0/2","deputShip 0/18","kazimierzShip 0/8","lateranoShip 0/95","preciShip 0/49","raidShip 0/15","sargonShip 0/2","skillfulShip 0/31","suntShip 0/16","swiftShip 0/81","visiShip 0/15"]
"bonds": ["arcaneShip 0/2","deputShip 0/18","kazimierzShip 0/8","lateranoShip 0/115","preciShip 0/49","raidShip 0/15","sargonShip 0/2","skillfulShip 0/31","suntShip 0/16","swiftShip 0/71","visiShip 0/15"]
}
},
"standIns": {
+305 -306
View File
File diff suppressed because it is too large. Load diff
+128 -128
View File
@@ -20,58 +20,58 @@
"time": 170,
"ticks": 5100,
"reason": "timeout",
"killed": 21,
"killed": 17,
"total": 50,
"unspawned": 0,
"bossHpLeft": null,
"rngDraws": 402,
"rngDraws": 620,
"errors": {"count":0,"kinds":[]},
"players": {
"p1": {
"killed": 21,
"killed": 17,
"total": 50,
"perfect": false,
"leaks": 29,
"leaks": 33,
"leaksUncounted": 0,
"coins": 4,
"dmg": 284159,
"dmg": 240621,
"bossDmg": 0,
"heal": 26726,
"deaths": 22,
"layerGains": {"raidShip":14,"visiShip":2}
"heal": 17519,
"deaths": 24,
"layerGains": {"raidShip":13,"visiShip":2}
}
},
"units": [
["p1",1,"op","chess_char_3_12_a",2,null,0,0,67,4,56082,3680,0,37,3],
["p1",2,"op","chess_char_4_09_a",0,null,0,0,77,3,56268,5968,0,34,2],
["p1",3,"op","chess_char_3_05_a",2,null,2109.99,1,74,4,33622,8823,0,39,2],
["p1",4,"op","chess_char_3_18_a",2,null,0,0,7,3,33048,9522,0,77,2],
["p1",5,"op","chess_char_4_04_a",1,null,435.7,1,80,0,2375,13673,0,113,0],
["p1",6,"op","chess_char_4_07_a",1,null,0,0,71,1,16766,11343,0,37,1],
["p1",7,"op","chess_char_4_16_a",1,null,807.8,1,85,3,27738,6036,0,83,0],
["p1",8,"op","chess_char_3_01_a",2,null,1271,1,5,1,16680,0,0,152,3],
["p1",9,"op","chess_char_3_04_a",2,null,1218,1,8,0,0,587,26726,59,3],
["p1",10,"op","chess_char_3_21_a",2,null,1272,1,84,1,21722,1272,0,62,1],
["p1",11,"op","chess_char_4_02_a",1,null,1272,1,82,1,9400,1724,0,71,1],
["p1",12,"op","chess_char_4_13_a",1,null,0,0,78,0,10458,1624,0,28,1]
["p1",1,"op","chess_char_3_12_a",2,null,0,0,72,3,40439,3657,0,19,2],
["p1",2,"op","chess_char_4_09_a",0,null,0,0,1,2,32698,2984,0,17,1],
["p1",3,"op","chess_char_3_05_a",2,null,2505,1,74,2,29899,11886,0,45,2],
["p1",4,"op","chess_char_3_18_a",2,null,0,0,7,1,14915,3668,0,36,1],
["p1",5,"op","chess_char_4_04_a",1,null,497.45,1,91,2,12814,6576,0,82,0],
["p1",6,"op","chess_char_4_07_a",1,null,0,0,75,1,18472,13600,0,43,1],
["p1",7,"op","chess_char_4_16_a",1,null,0,0,88,0,3482,9543,0,103,0],
["p1",8,"op","chess_char_3_01_a",2,null,1271,1,5,0,19777,0,0,141,2],
["p1",9,"op","chess_char_3_04_a",2,null,1218,1,84,0,0,1599,17519,35,2],
["p1",10,"op","chess_char_3_21_a",2,null,716.85,1,6,4,45212,555,0,138,2],
["p1",11,"op","chess_char_4_02_a",1,null,1272,1,90,2,12787,1653,0,68,1],
["p1",12,"op","chess_char_4_13_a",1,null,0,0,86,0,10126,1624,0,26,1]
],
"enemies": {
"enemy_10001_trslim": [1,1,0,8,4860],
"enemy_1000_gopro_2": [1,1,0,22,1836],
"enemy_10018_sgrobh": [1,1,0,2668,8100],
"enemy_1001_bigbo": [1,0,1,0,2592],
"enemy_10027_vtsk": [1,0,1,11845,916],
"enemy_10001_trslim": [1,1,0,17,4860],
"enemy_1000_gopro_2": [1,1,0,0,1836],
"enemy_10018_sgrobh": [1,1,0,2810,8100],
"enemy_1001_bigbo": [1,0,1,1235,2581],
"enemy_10027_vtsk": [1,0,1,15097,2542],
"enemy_10031_cnvsld": [1,0,1,0,0],
"enemy_10034_cnvsax": [1,0,1,0,0],
"enemy_10042_prtrop": [1,0,1,808,3807],
"enemy_1116_liprr_2": [21,12,9,5388,124143],
"enemy_1119_vofsd": [12,5,6,21861,99812],
"enemy_1121_lifbos_2": [9,1,7,13749,38094]
"enemy_10034_cnvsax": [1,0,1,364,2496],
"enemy_10042_prtrop": [1,0,1,0,0],
"enemy_1116_liprr_2": [21,11,10,5655,116700],
"enemy_1119_vofsd": [12,2,8,13284,62929],
"enemy_1121_lifbos_2": [9,1,7,11244,38577]
},
"hooks": [1,85,5100,943,943,1330,1321,3766,43,76,19,28,0,21170,28,44,50,27,1,43,6,0,9],
"events": {"atk":1028,"bounty":2,"deploy":35,"die":49,"dmg":1321,"fx":68,"heal":59,"layer":6,"leak":27,"skill":35,"spawn":62,"status":134},
"fx": {"blink":6,"dodge":9,"dp":7,"garrison":6,"liberate":15,"slash":24,"telegraph":1},
"snaps": "e6528b42 398001f2 644c5ee8 df7b48f9 a8a51847 554e1092 13c60701 49f04e5d fb95fb75 38fa86a2 687082e0 9c39cb98 7dd1bdd1 a74eebb6 b9c1e236 8fc6086d 944683e9"
"hooks": [1,91,5100,870,870,1441,1438,3866,41,82,15,33,0,18850,26,37,50,30,1,42,5,0,6],
"events": {"atk":1013,"bounty":2,"deploy":41,"die":52,"dmg":1438,"fx":62,"heal":35,"layer":5,"leak":30,"skill":28,"spawn":62,"status":126},
"fx": {"beam":4,"blink":11,"dodge":6,"dp":5,"garrison":5,"liberate":14,"slash":16,"telegraph":1},
"snaps": "c7e5e922 eab4c908 ad04ab78 0424dbc9 6eff6ee3 2b3bded9 3edb2c2b 02ffd9b9 6202ecfa f7f93735 4f3faeff 59df56c7 3b5b29d0 e6bceddc 4d139a38 ea4edd9b b54828d9"
},
"standin-02": {
"about": "normal band 5 as stand-ins: chess_char_4_17_a→char_610_acfend chess_char_4_18_a→char_602_cdfend chess_char_5_05_a→char_602_cdfend chess_char_4_19_a→char_608_acpion chess_char_5_01_a→char_600_cpione chess_char_4_22_a→char_609_acguad chess_char_4_23_a→char_609_acguad chess_char_5_06_a→char_609_acguad chess_char_4_20_a→char_603_csnipe chess_char_4_24_a→char_604_ccast chess_char_5_02_a→char_604_ccast chess_char_5_03_a→char_612_accast",
@@ -138,44 +138,44 @@
"time": 190,
"ticks": 5700,
"reason": "timeout",
"killed": 37,
"killed": 46,
"total": 74,
"unspawned": 0,
"bossHpLeft": null,
"rngDraws": 374,
"rngDraws": 247,
"errors": {"count":0,"kinds":[]},
"players": {"p1":{"killed":37,"total":74,"perfect":false,"leaks":37,"leaksUncounted":0,"coins":8,"dmg":331499,"bossDmg":0,"heal":49226,"deaths":12,"layerGains":{}}},
"players": {"p1":{"killed":46,"total":74,"perfect":false,"leaks":28,"leaksUncounted":0,"coins":8,"dmg":342938,"bossDmg":0,"heal":45325,"deaths":12,"layerGains":{}}},
"units": [
["p1",1,"op","chess_char_5_08_a",2,null,0,0,6,0,4409,3444,0,59,1],
["p1",2,"op","chess_char_5_14_a",2,null,0,0,86,16,131680,8403,0,53,6],
["p1",3,"op","chess_char_5_19_a",0,null,0,0,90,8,38187,15644,0,91,2],
["p1",4,"op","chess_char_5_07_a",2,null,0,0,7,2,18936,10110,0,69,2],
["p1",5,"op","chess_char_5_13_a",2,null,1872.24,1,11,5,68168,12979,0,127,4],
["p1",6,"op","chess_char_5_17_a",2,null,0,0,81,2,7848,5571,0,85,0],
["p1",7,"op","chess_char_5_10_a",2,null,932,1,2,1,8617,0,0,74,2],
["p1",8,"op","chess_char_5_11_a",2,null,1224,1,3,0,0,0,49226,72,2],
["p1",9,"op","chess_char_5_12_a",2,null,1160,1,4,0,22812,0,0,88,2],
["p1",10,"op","chess_char_5_15_a",2,null,0,0,85,2,8089,12138,0,87,2],
["p1",11,"op","chess_char_5_18_a",2,null,0,0,1,1,13952,1272,0,34,1],
["p1",12,"op","chess_char_5_20_a",2,null,742,1,91,0,8800,3202,0,43,1]
["p1",1,"op","chess_char_5_08_a",2,null,515.8,1,6,0,11779,9335,0,131,2],
["p1",2,"op","chess_char_5_14_a",2,null,0,0,89,24,159150,7595,0,61,6],
["p1",3,"op","chess_char_5_19_a",0,null,0,0,90,6,38255,15228,0,94,2],
["p1",4,"op","chess_char_5_07_a",2,null,2564,1,91,2,10656,2984,0,18,1],
["p1",5,"op","chess_char_5_13_a",2,null,0,0,11,7,58468,14481,0,126,4],
["p1",6,"op","chess_char_5_17_a",2,null,1154,1,93,3,11205,3361,0,59,0],
["p1",7,"op","chess_char_5_10_a",2,null,932,1,2,0,8982,0,0,77,2],
["p1",8,"op","chess_char_5_11_a",2,null,1224,1,3,0,0,0,45325,72,2],
["p1",9,"op","chess_char_5_12_a",2,null,1160,1,4,1,22227,0,0,86,2],
["p1",10,"op","chess_char_5_15_a",2,null,0,0,84,2,8190,12762,0,91,2],
["p1",11,"op","chess_char_5_18_a",2,null,0,0,1,0,5656,1272,0,20,1],
["p1",12,"op","chess_char_5_20_a",2,null,1972,1,92,1,8370,1972,0,35,1]
],
"enemies": {
"enemy_1006_shield_2": [1,1,0,679,8000],
"enemy_1006_shield_3": [1,0,1,11277,13035],
"enemy_1006_shield_3": [1,0,1,12959,19581],
"enemy_10073_mpcar": [1,1,0,12,1600],
"enemy_1007_slime": [1,1,0,0,440],
"enemy_10081_mpplai": [1,1,0,0,2000],
"enemy_10087_hlchgr": [1,1,0,58,4800],
"enemy_10094_crstf": [1,1,0,28,3200],
"enemy_10097_crshd": [1,0,1,936,5046],
"enemy_1166_dusbr_2": [42,27,15,3496,107410],
"enemy_1170_dushld_2": [12,2,8,27941,44857],
"enemy_9011_acrefr": [12,2,4,28337,141112]
"enemy_10097_crshd": [1,1,0,0,8000],
"enemy_1166_dusbr_2": [42,31,11,3354,115737],
"enemy_1170_dushld_2": [12,6,4,28840,54328],
"enemy_9011_acrefr": [12,2,3,23060,125251]
},
"hooks": [1,91,5700,1118,1118,1648,1663,132,49,78,25,27,0,27793,3468,54,74,29,1,49,0,1,9],
"events": {"atk":1244,"bounty":4,"deploy":17,"die":49,"dmg":1661,"fx":130,"heal":126,"leak":29,"skill":50,"spawn":86,"status":661},
"fx": {"aoe":30,"burst":1,"displace":1,"dodge":16,"dp":22,"phase":1,"slash":48,"sp":1,"spGain":10},
"snaps": "dbcb5cec 56a8a8f6 e8d97a5d d2594a66 b6f753a4 6b5239d5 0d94f1a8 53bcdab2 582202c7 d547ef42 438122c0 f5345cd2 dbac677c 38aa1103 537a6dbf c9e9e9aa 7c7ed647 9cfd6d5b 94abfb24"
"hooks": [1,93,5700,1154,1154,1775,1770,135,58,77,25,27,0,28761,3090,58,74,19,1,58,0,0,8],
"events": {"atk":1247,"bounty":4,"deploy":19,"die":58,"dmg":1767,"fx":170,"heal":124,"leak":19,"skill":50,"spawn":86,"status":614},
"fx": {"aoe":60,"displace":1,"dodge":18,"dp":30,"phase":1,"slash":48,"sp":2,"spGain":10},
"snaps": "dbcb5cec 56a8a8f6 e8d97a5d d2594a66 b6f753a4 78a2f35e 80349f15 2cd292dd d7240cae 4f120b33 69d90058 45d5da9a ae0b244b 17b17251 4df0cf30 f2c7c569 baa94919 07ba89e9 e4a68e4d"
},
"standin-04": {
"about": "normal band 6 as stand-ins: chess_char_6_03_a→char_610_acfend chess_char_6_02_a→char_608_acpion chess_char_6_07_a→char_617_sharp2 chess_char_6_10_a→char_617_sharp2 chess_char_6_11_a→char_608_acpion chess_char_6_06_a→char_609_acguad chess_char_5_22_a→char_611_acnipe chess_char_6_01_a→char_611_acnipe chess_char_6_04_a→char_614_acsupo chess_char_6_05_a→char_611_acnipe chess_char_6_08_a→char_612_accast chess_char_6_09_a→char_613_acmedc",
@@ -241,7 +241,7 @@
"hooks": [1,181,6051,918,918,1945,1944,62,148,170,25,24,0,31170,4160,44,158,22,1,149,2,0,13],
"events": {"atk":1080,"bounty":4,"deploy":21,"die":148,"dmg":1944,"fx":87,"heal":45,"layer":2,"leak":22,"skill":49,"spawn":172,"status":440},
"fx": {"aoe":7,"dodge":13,"dp":18,"garrison":2,"revive":1,"slash":29,"sp":12,"spGain":3,"telegraph":2},
"snaps": "29a29463 6fc96b2d 184b448a fce3c126 45d67357 2b2b80de f966fc58 66e1b5c9 ce0eff29 79805bf9 289d6433 dbecb111 d3142708 bec781dd 26e4cc8e 0c071920 829264cd 362b2f26 16b5df6a 9fda7720 7730ec59"
"snaps": "29a29463 6fc96b2d 184b448a fce3c126 45d67357 4c47175a 1292297b 3e42d44e b7bf91a6 dd4e2386 0b4615ac 81792172 a056e50b 7e87af96 dd9818ad 8c9001ef b2db6556 9bf17d05 66cf3ead 709fbe1f c88b2f46"
},
"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",
@@ -303,31 +303,31 @@
"round": 10,
"seed": 1442657168,
"waveId": "act1autochess_h03",
"time": 185.83,
"ticks": 5575,
"time": 182.77,
"ticks": 5483,
"reason": "cleared",
"killed": 40,
"killed": 42,
"total": 98,
"unspawned": 0,
"bossHpLeft": null,
"rngDraws": 293,
"rngDraws": 309,
"errors": {"count":0,"kinds":[]},
"players": {
"p1": {"killed":40,"total":98,"perfect":false,"leaks":58,"leaksUncounted":0,"coins":8,"dmg":553335,"bossDmg":0,"heal":19916,"deaths":32,"layerGains":{"raidShip":24}}
"p1": {"killed":42,"total":98,"perfect":false,"leaks":56,"leaksUncounted":0,"coins":8,"dmg":577212,"bossDmg":0,"heal":19789,"deaths":32,"layerGains":{"raidShip":26}}
},
"units": [
["p1",1,"op","chess_char_3_12_b",2,"none",1904,1,135,10,142984,5468,880,20,3],
["p1",1,"op","chess_char_3_12_b",2,"none",1904,1,142,10,142532,5468,880,20,3],
["p1",2,"op","chess_char_4_09_b",0,"none",0,0,6,7,58726,3510,0,13,1],
["p1",3,"op","chess_char_3_05_b",2,"none",0,0,90,1,27607,9128,0,18,2],
["p1",4,"op","chess_char_3_18_b",2,"none",0,0,89,3,34118,9190,2808,27,2],
["p1",5,"op","chess_char_4_04_b",1,"none",0,0,134,1,8258,8846,0,21,0],
["p1",6,"op","chess_char_4_07_b",1,"none",0,0,93,0,19765,10676,0,20,1],
["p1",7,"op","chess_char_4_16_b",1,"none",0,0,133,2,17401,11631,0,26,0],
["p1",8,"op","chess_char_3_01_b",2,"none",0,0,128,1,21787,3020,0,27,1],
["p1",3,"op","chess_char_3_05_b",2,"none",0,0,93,2,26911,9128,0,18,2],
["p1",4,"op","chess_char_3_18_b",2,"none",0,0,92,3,34127,9062,2680,27,2],
["p1",5,"op","chess_char_4_04_b",1,"none",0,0,141,0,16294,10620,0,30,0],
["p1",6,"op","chess_char_4_07_b",1,"none",0,0,96,0,28260,10676,0,25,1],
["p1",7,"op","chess_char_4_16_b",1,"none",0,0,139,4,24443,16559,0,44,0],
["p1",8,"op","chess_char_3_01_b",2,"none",0,0,132,1,21262,3020,0,27,1],
["p1",9,"op","chess_char_3_04_b",2,"none",0,0,4,0,0,6998,16229,17,2],
["p1",10,"op","chess_char_3_21_b",2,"none",0,0,114,11,155605,7911,0,47,1],
["p1",10,"op","chess_char_3_21_b",2,"none",0,0,114,12,159580,7911,0,50,1],
["p1",11,"op","chess_char_4_02_b",1,"none",0,0,2,3,47003,1483,0,29,1],
["p1",12,"op","chess_char_4_13_b",1,"none",0,0,96,1,20081,3262,0,25,2]
["p1",12,"op","chess_char_4_13_b",1,"none",0,0,99,0,18075,3262,0,24,2]
],
"enemies": {
"enemy_10162_mnctpt": [1,1,0,7990,39813],
@@ -338,14 +338,14 @@
"enemy_1025_reveng": [1,1,0,0,12442],
"enemy_1026_aghost": [1,1,0,0,9456],
"enemy_1043_zomsbr": [1,0,1,0,0],
"enemy_1251_lysyta_2": [57,25,32,15811,231796],
"enemy_1252_lysytb_2": [21,7,14,21523,186411],
"enemy_1329_cbshld_2": [12,1,11,28332,50624]
"enemy_1251_lysyta_2": [57,26,31,15933,233652],
"enemy_1252_lysytb_2": [21,8,13,23530,207750],
"enemy_1329_cbshld_2": [12,1,11,32779,51307]
},
"hooks": [1,135,5575,471,471,727,756,61,72,134,16,33,0,6314,36,49,98,58,1,81,3,0,6],
"events": {"atk":553,"bounty":4,"deploy":37,"die":76,"dmg":756,"fx":57,"heal":58,"layer":3,"leak":58,"skill":32,"spawn":110,"status":119},
"fx": {"blink":4,"camouflage":1,"dodge":11,"dp":13,"explode":1,"garrison":3,"slash":24},
"snaps": "2e7a8cb5 d50cd79b d7949cae 1b9749a6 6e3d202d f87f73b6 45e24574 d9fad5af 5495e86c 3357c483 195f9b7f 05cf2852 258f0a18 7db86d77 fcd4dcb8 b89c90a0 d44a9d5e 0de542a5 f00c7481"
"hooks": [1,142,5483,525,525,773,799,61,74,141,16,40,0,6475,34,57,98,56,1,82,4,0,7],
"events": {"atk":605,"bounty":4,"deploy":44,"die":85,"dmg":799,"fx":65,"heal":57,"layer":4,"leak":56,"skill":32,"spawn":110,"status":114},
"fx": {"blink":11,"camouflage":1,"dodge":11,"dp":13,"explode":1,"garrison":4,"slash":24},
"snaps": "2e7a8cb5 d50cd79b d7949cae 1b9749a6 6e3d202d f87f73b6 b1e5a323 226ab559 3962f99c b1192e86 1eb20f4b be395d5b 618f2a05 d9a8eb7c b36cfafe 0c3a2649 cb88aa80 0533b183 5054650e"
},
"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",
@@ -426,47 +426,47 @@
"time": 230,
"ticks": 6900,
"reason": "timeout",
"killed": 32,
"killed": 43,
"total": 179,
"unspawned": 0,
"bossHpLeft": null,
"rngDraws": 1052,
"rngDraws": 1025,
"errors": {"count":0,"kinds":[]},
"players": {"p1":{"killed":32,"total":179,"perfect":false,"leaks":147,"leaksUncounted":0,"coins":2,"dmg":1703220,"bossDmg":0,"heal":106481,"deaths":9,"layerGains":{}}},
"players": {"p1":{"killed":43,"total":179,"perfect":false,"leaks":136,"leaksUncounted":0,"coins":2,"dmg":2172511,"bossDmg":0,"heal":95038,"deaths":13,"layerGains":{}}},
"units": [
["p1",1,"op","chess_char_5_08_b",2,"uniequip_002_acfend",3285.08,1,201,4,80453,15794,0,116,3],
["p1",2,"op","chess_char_5_14_b",2,"uniequip_002_acpion",1904,1,200,8,678474,11374,0,31,9],
["p1",3,"op","chess_char_5_19_b",0,"uniequip_002_sharp2",4154.5,1,202,4,187598,17962,0,51,2],
["p1",4,"op","chess_char_5_07_b",2,"none",3334,1,199,2,46104,18401,0,36,3],
["p1",5,"op","chess_char_5_13_b",2,"uniequip_002_acguad",0,0,160,5,101185,25518,0,50,3],
["p1",6,"op","chess_char_5_17_b",2,"uniequip_002_acspec",1448,1,8,2,21853,46495,0,206,0],
["p1",7,"op","chess_char_5_10_b",2,"none",1131,1,4,1,46614,0,0,155,4],
["p1",8,"op","chess_char_5_11_b",2,"uniequip_002_acmedc",2262.4,1,5,0,0,0,106481,74,3],
["p1",9,"op","chess_char_5_12_b",2,"uniequip_002_acsupo",1430,1,11,2,97118,0,0,130,3],
["p1",10,"op","chess_char_5_15_b",2,"none",1510,1,13,0,84181,0,0,228,4],
["p1",11,"op","chess_char_5_18_b",2,"uniequip_002_acnipe",2380.5,1,6,4,265046,0,0,156,3],
["p1",12,"op","chess_char_5_20_b",2,"uniequip_002_acsupo",1430,1,14,0,94594,0,0,125,3],
["p1",1,"op","chess_char_5_08_b",2,"uniequip_002_acfend",3371,1,203,4,94861,14912,0,116,3],
["p1",2,"op","chess_char_5_14_b",2,"uniequip_002_acpion",0,0,124,14,988772,21777,0,61,10],
["p1",3,"op","chess_char_5_19_b",0,"uniequip_002_sharp2",4154.5,1,205,8,235963,23398,0,64,2],
["p1",4,"op","chess_char_5_07_b",2,"none",3334,1,204,2,34977,19978,0,29,2],
["p1",5,"op","chess_char_5_13_b",2,"uniequip_002_acguad",0,0,161,5,103856,25240,0,51,3],
["p1",6,"op","chess_char_5_17_b",2,"uniequip_002_acspec",1448,1,200,4,83107,24504,0,112,0],
["p1",7,"op","chess_char_5_10_b",2,"none",1131,1,4,2,79514,0,0,153,4],
["p1",8,"op","chess_char_5_11_b",2,"uniequip_002_acmedc",2262.4,1,5,0,0,0,95038,74,3],
["p1",9,"op","chess_char_5_12_b",2,"uniequip_002_acsupo",1430,1,11,0,112393,0,0,146,3],
["p1",10,"op","chess_char_5_15_b",2,"none",1510,1,13,0,77843,0,0,215,4],
["p1",11,"op","chess_char_5_18_b",2,"uniequip_002_acnipe",2380.5,1,6,4,262886,0,0,169,3],
["p1",12,"op","chess_char_5_20_b",2,"uniequip_002_acsupo",1430,1,14,0,98338,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,1,0,39568,92876],
"enemy_1092_mdgint": [1,0,1,0,67],
"enemy_1081_sotisd": [1,0,1,0,27122],
"enemy_1092_mdgint": [1,0,1,1448,67],
"enemy_1116_liprr": [1,0,1,0,7702],
"enemy_1116_liprr_2": [1,0,1,0,1829],
"enemy_1118_lidbox_2": [1,0,1,0,1344],
"enemy_1119_vofsd": [1,0,1,0,959],
"enemy_1121_lifbos": [1,0,1,0,922],
"enemy_1249_lysdb_2": [60,9,49,23770,693077],
"enemy_1251_lysyta": [63,20,43,6676,488381],
"enemy_1254_lypa_2": [48,1,47,62523,378913]
"enemy_1119_vofsd": [1,0,1,0,889],
"enemy_1121_lifbos": [1,0,1,0,1525],
"enemy_1249_lysdb_2": [60,13,44,41971,986578],
"enemy_1251_lysyta": [63,28,35,8822,665956],
"enemy_1254_lypa_2": [48,1,47,74560,442348]
},
"hooks": [1,202,6900,1760,1760,3076,3094,145,41,186,40,39,0,26130,16747,54,179,145,1,45,0,0,8],
"events": {"atk":1979,"bounty":1,"deploy":20,"die":41,"dmg":3094,"fx":274,"heal":126,"leak":145,"skill":79,"spawn":194,"status":1237},
"fx": {"aoe":84,"dodge":29,"dp":17,"shieldBreak":60,"slash":72,"sp":5,"spGain":7},
"snaps": "4d4dc5ab 98e9e455 46d76035 722418a9 b67e68a3 866e42e8 786ec7e2 2c2a7307 3657963b 8fad1c0c 513f1b73 84a84fa5 d1698d65 9ae19dde 551dcc8c 8e2b8aef a8f4f525 70f7b5a7 f8b9e9b9 0c6627fe 9c4013d8 fa4c2add 6f3c1f53"
"hooks": [1,205,6900,1764,1764,3493,3533,147,56,189,40,44,0,26478,16569,72,179,133,1,59,0,0,10],
"events": {"atk":2013,"bounty":1,"deploy":23,"die":56,"dmg":3508,"fx":308,"heal":130,"leak":133,"skill":80,"spawn":194,"status":1297},
"fx": {"aoe":90,"displace":12,"dodge":31,"dp":24,"shieldBreak":59,"slash":80,"sp":1,"spGain":11},
"snaps": "4d4dc5ab 00efc642 4dc3aa32 13e9533b a3617bdf 587927d0 9fe3b7b8 0b39dceb 2981edf9 2ba1ce8c ef825d5b 85fd9608 a83f0a12 9e6b1271 7c5bf7ee f6ad8d8e c76286f6 037365de bf979497 771a38f7 b74aaf11 518326a3 19e5e338"
},
"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",
@@ -477,31 +477,31 @@
"round": 13,
"seed": 2308517178,
"waveId": "act1autochess_h06",
"time": 199.53,
"ticks": 5986,
"time": 198.9,
"ticks": 5967,
"reason": "cleared",
"killed": 158,
"total": 158,
"unspawned": 0,
"bossHpLeft": null,
"rngDraws": 279,
"rngDraws": 257,
"errors": {"count":0,"kinds":[]},
"players": {
"p1": {"killed":158,"total":158,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":8,"dmg":924432,"bossDmg":0,"heal":29522,"deaths":0,"layerGains":{"sargonShip":16}}
"p1": {"killed":158,"total":158,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":8,"dmg":924432,"bossDmg":0,"heal":30129,"deaths":1,"layerGains":{"sargonShip":20}}
},
"units": [
["p1",1,"op","chess_char_6_03_b",2,"uniequip_002_acfend",4974.95,1,8,0,0,0,0,0,0],
["p1",2,"op","chess_char_6_02_b",2,"uniequip_002_acpion",1904,1,6,0,0,0,0,0,0],
["p1",3,"op","chess_char_6_07_b",0,"uniequip_002_sharp2",2494,1,9,0,0,0,0,0,0],
["p1",4,"op","chess_char_6_10_b",0,"uniequip_002_sharp2",2494,1,11,24,119442,0,0,173,3],
["p1",5,"op","chess_char_6_11_b",2,"uniequip_002_acpion",1624,1,13,38,184185,11513,0,52,20],
["p1",6,"op","chess_char_6_06_b",2,"uniequip_002_acguad",3396,1,14,19,66075,855,0,156,4],
["p1",4,"op","chess_char_6_10_b",0,"uniequip_002_sharp2",2494,1,11,20,146204,0,0,174,4],
["p1",5,"op","chess_char_6_11_b",2,"uniequip_002_acpion",1834,1,13,45,168227,12564,0,58,23],
["p1",6,"op","chess_char_6_06_b",2,"uniequip_002_acguad",3531,1,14,10,62057,943,0,157,4],
["p1",7,"op","chess_char_5_22_b",2,"uniequip_002_acnipe",1587,1,4,0,0,0,0,0,0],
["p1",8,"op","chess_char_6_01_b",2,"uniequip_002_acnipe",1643,1,5,0,0,0,0,0,0],
["p1",9,"op","chess_char_6_04_b",2,"uniequip_002_acsupo",83.4,1,15,11,95944,2382,0,135,2],
["p1",10,"op","chess_char_6_05_b",2,"uniequip_002_acnipe",1643,1,7,19,77978,0,0,93,2],
["p1",11,"op","chess_char_6_08_b",2,"uniequip_002_accast",1819,1,10,47,380809,0,0,82,2],
["p1",12,"op","chess_char_6_09_b",2,"uniequip_002_acmedc",1324,1,12,0,0,17709,29522,83,2],
["p1",9,"op","chess_char_6_04_b",2,"uniequip_002_acsupo",2465,1,137,8,65378,2465,0,91,2],
["p1",10,"op","chess_char_6_05_b",2,"uniequip_002_acnipe",1643,1,7,22,90616,0,0,96,2],
["p1",11,"op","chess_char_6_08_b",2,"uniequip_002_accast",1819,1,10,53,391951,0,0,83,2],
["p1",12,"op","chess_char_6_09_b",2,"uniequip_002_acmedc",1394,1,12,0,0,16762,30129,83,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]
@@ -512,17 +512,17 @@
"enemy_1148_dssbr_2": [1,1,0,0,3456],
"enemy_1158_divman": [1,1,0,195,3168],
"enemy_1160_hvyslr": [1,1,0,0,9600],
"enemy_1160_hvyslr_2": [1,1,0,0,13440],
"enemy_1161_tidmag": [1,1,0,1363,5760],
"enemy_1161_tidmag_2": [1,1,0,824,7680],
"enemy_1249_lysdb_2": [60,60,0,1374,345600],
"enemy_1160_hvyslr_2": [1,1,0,133,13440],
"enemy_1161_tidmag": [1,1,0,1336,5760],
"enemy_1161_tidmag_2": [1,1,0,1391,7680],
"enemy_1249_lysdb_2": [60,60,0,1459,345600],
"enemy_1251_lysyta": [51,51,0,0,134640],
"enemy_1329_cbshld": [39,39,0,3643,374400]
"enemy_1329_cbshld": [39,39,0,3019,374400]
},
"hooks": [1,173,5986,867,867,1620,1744,149,158,158,35,34,0,31554,3298,63,158,0,1,158,2,1,21],
"events": {"atk":965,"bounty":4,"deploy":12,"die":158,"dmg":1722,"fx":309,"heal":116,"layer":2,"skill":69,"spawn":173,"status":425},
"fx": {"aoe":2,"burst":1,"dodge":27,"dp":58,"garrison":2,"shieldBreak":60,"slash":146,"sp":13},
"snaps": "268546d4 ec010f3d d556f759 749d85b5 fd1848fa 9a69b0ed 35a96974 ceeb72dd adfeed08 f497b058 ffade80c ec17b5c7 49c46293 8eebc960 34dab525 36f0055b b3c7d1bd 036e5819 41df2c8f 33def1f4"
"hooks": [1,174,5967,836,836,1660,1803,179,159,159,40,38,0,28209,2688,60,158,0,1,159,3,1,23],
"events": {"atk":974,"bounty":4,"deploy":13,"die":159,"dmg":1782,"fx":330,"heal":135,"layer":3,"skill":78,"spawn":173,"status":334},
"fx": {"aoe":2,"burst":1,"dodge":28,"dp":68,"garrison":3,"shieldBreak":60,"slash":152,"sp":16},
"snaps": "526d4c63 f04a2d68 53d511ef 5f8b4334 d796abdd 122e9876 81bad943 4c6a838a eb463850 1e1d2025 875b599b 2d763f55 51548a07 73b07326 88a8ea6f ec211cd8 e329b226 03d1aa7b 63fd2bb2 afee939a"
},
"standin-10": {
"about": "elite band 7 as stand-ins: chess_char_6_17_b→char_608_acpion chess_char_6_13_b→char_615_acspec chess_char_6_19_b→char_615_acspec chess_char_6_12_b→char_612_accast chess_char_6_15_b→char_614_acsupo chess_char_6_18_b→char_612_accast chess_char_6_20_b→char_613_acmedc",
@@ -569,10 +569,10 @@
"enemy_1169_duphlx": [1,0,1,0,0],
"enemy_1402_tgshd_2": [36,2,34,29224,197345]
},
"hooks": [1,165,6486,549,549,865,877,6809,50,159,17,36,0,8486,1125,49,131,106,1,50,1,1,0],
"hooks": [1,165,6486,549,549,865,877,6809,50,159,17,36,0,8308,1125,49,131,106,1,50,1,1,0],
"events": {"atk":554,"deploy":32,"die":53,"dmg":802,"fx":530,"heal":21,"layer":1,"leak":106,"skill":34,"spawn":140,"status":378},
"fx": {"aoe":4,"blink":3,"burst":1,"displace":17,"dodge":3,"dp":17,"expose":414,"garrison":1,"garrisonGrant":3,"slash":67},
"snaps": "80709a69 1b180600 2040e410 16970933 0b0b610d 4e3060e6 d2f5fa1d d015c650 26f1c266 9350b3c3 ad710861 7c181d0b d41c00a0 64db1e01 858cfe5f 40faa038 5cf23687 498f5f47 50bc9ad2 848c94df 4806ebb3 9bfdaf83"
"snaps": "80709a69 1b180600 2040e410 16970933 7ec28fab 061d6583 09f2da3e 98333fee 741e4051 c5f8165a 55db9474 b9b2bf46 d72aea5d 20d591d8 3077f062 ab32900d eb4540a2 37c492a6 3e3cd8f7 20a4cb8e 22ada53e b9ce62f2"
}
}
}
+6 -4
View File
@@ -96,7 +96,7 @@ test('splash casters hit enemies around the target; chain casters bounce with fa
assert.deepEqual(hit.slice().sort((x, y) => y - x), [1000, 850, 723, 614]);
});
test('ring healers heal three allies; bards heal everyone in range every second', () => {
test('ring healers heal three allies; bards give everyone in range 生命回复速度 +10 % of their ATK (PRTS 分支特性信息 吟游者)', () => {
const ally = (id) => chessRec({ id, profession: 'TANK', skill: null, stats: { maxHp: 10000, atk: 0 } });
const h = makeBattle({
defs: {
@@ -119,10 +119,12 @@ test('ring healers heal three allies; bards heal everyone in range every second'
content: 'none',
});
h2.step();
h2.run(0.3);
for (const id of ['a1', 'a2', 't_bard']) approx(h2.unit(id).s.hpRegen, 100); // an hpRegen buff, not a heal
h2.unit('a1').hp = 1000; h2.unit('a2').hp = 1000;
h2.run(3.05);
approx(h2.unit('a1').hp, 1000 + 3 * 100);
approx(h2.unit('a2').hp, 1000 + 3 * 100);
h2.run(3);
// the regeneration lands as the HP ticks over (at most 1 HP pending)
for (const id of ['a1', 'a2']) assert.ok(Math.abs(h2.unit(id).hp - (1000 + 3 * 100)) <= 1.5, `${id}: ${h2.unit(id).hp}`);
assert.equal(h2.unit('t_bard').stats.attacks, 0);
});