feedback5 R19G: 蕾缪安's S3 no longer ends by itself when nothing is in her range — it keeps its bullets and locks and locks the next enemy that comes; the bombardment follows only when the bullets are spent (community report); golden: 3 scenarios move
Seen (community report 「蕾缪安3技能范围里没人好像会自动结束」, relayed by the owner): with S3 locking, the locked enemy
killed or walking out of her range and nobody else in it, the skill ended at the next lock tick — the shells fell at
once and the bullets left were thrown away (repro on 0255afd: 3 of 5 bullets lost; a walker leaving her range, 1 lost).
Cause: chess_char_6_01-lemuen.js:169 `if (!e) { if (m.lemLocks.length) skill.end('ammo'); return; }`, there since the
initial import with no decision behind it.
Official: 「攻击装有5发弹药,打完后结束(可随时停止技能)」 — an ammo skill ends when its bullets are spent or the player
stops it; PRTS 卫戍协议/帮助 技能操作 「通常不会自动关闭技能」 (only 玛露希尔's 召唤使魔 is closed automatically); the client
(charpack char_4193_lemuen, buff_template_data lemuen_s_3): the S3 lock is an attack that needs a target and the skill
buff switches to the bombardment mode on ON_BUFF_FINISH only.
Now: with nothing to lock the skill waits (bullets and locks kept, the marks following their enemies or staying where
they left), its lock ready, so the next enemy in range (or 通缉) is locked on the next tick; it ends when the bullets are
spent and the shells fall on every mark in lock order as before. The S3 'lock' fx carry `hold`: render/fx/locks.js keeps
those reticles while the shooter's skill bit (UF.SKILL) is on and starts their LOCK_T at the skill's end (they faded 5 s
into a wait otherwise); S2's aim lock keeps its timeout.
Golden — traced on both trees (SkillRuntime start / end, the round's fields, the carried SP); in each the first
divergence is an S3 the parent ended with bullets left and nothing in her range:
- roster-018: the elite 蕾缪安's S3 of 7.63 s ended at 9.63 s with 2 of 6 bullets left; now the 6th goes at 12.00 s
(first differing snapshot window 0–10 s).
- boss-boss_3-pair: her S3 of 27.8 s ended at 30.3 s with 4 of 9 left; now all 9 by 34.43 s (window 30–40 s); the boss
now falls at 199.53 s instead of the 200 s cap.
- coop2-NORMAL-14-standins: ai_0's 蕾缪安 in round 11 ended S3 at 17.2 s (6 of 8 left) and 77.97 s (7 of 9); now she
spends them, enters the 联防 with 25.96 SP instead of 10.27, casts S3 there and kills one more of h_0's leaked enemies:
h_0 loses 1 LP less (rounds 11–12 LP 18 → 19, 8 → 9; lpLost 30 → 29; ai_0 kills +1).
bonds, standins, diy unchanged.
Tests: test/sim/feedback5-lemuen-s3-wait.test.js (3; the killed target and the walker who leaves fail on the parent),
test/render/fxproj.test.js +1 (a held lock waits while the skill bit is on; fails on the parent renderer).
Docs: CHANGELOG 0.2.0 规则(按官方), docs/history/0.2.0.md §25.22.8 (also notes, unchanged: S2 spends a bullet on every
normal attack where PRTS says only the 通缉 snipe does — left to the owner).
This commit is contained in:
1 parent
0255afd12b
commit
b87848a443
11 files changed
+286
-103
No files matched your search
@@ -70,6 +70,7 @@
|
||||
- 自制投石机「索敌不受阻挡影响」:被站在排气格栅上(隐匿)的干员阻挡、范围内又没有别的干员时不会攻击,和原版一样;其他敌人仍会攻击阻挡自己的隐匿干员(社区反馈)。
|
||||
- 升级调度中心后,新增的商品栏位立即放上新卡,不用等下一次刷新(社区反馈;官方教程「升级后将出现更多的商品栏位」)。
|
||||
- 被冻结或晕眩的敌人仍会被接触到的干员阻挡:干员再部署到它身边、或阻挡数空出来时会立即挡住它,隐匿的敌人也随之破隐,不用再等冻结或晕眩结束;沉睡、浮空、恐惧和不可阻挡的敌人仍然不会被阻挡(GitHub #232,感谢 @ccyl、@kukiC)。
|
||||
- 蕾缪安三技能锁定时攻击范围里没有敌人,技能不会再自动结束:剩余子弹和已有的锁定都保留,下一个敌人进入范围就立即继续锁定,子弹打完才结束并开始轰炸,等待期间锁定标记一直显示(社区反馈;弹药类技能打完才结束,PRTS 卫戍协议帮助「通常不会自动关闭技能」)。
|
||||
|
||||
### 界面
|
||||
|
||||
|
||||
@@ -1980,3 +1980,50 @@ here, each reproduced first; the rest were answered (not a bug, already fixed in
|
||||
the parent), `test/match/playtest6-matchflow.test.js` #235 (2; the 联防 one fails on the parent: losses = the LP
|
||||
settled, no result ticker, gone in the next phase), SP_E2E `test/ui/resultbox.e2e.test.js` (3, mock variants
|
||||
`unite[,through][,helper|,dead]`). Docs: PLAYING.md §1 / §5, design/network.md, design/client.md, design/match.md.
|
||||
|
||||
#### 25.22.8 Community report 「蕾缪安3技能范围里没人好像会自动结束」 (relayed by the owner): 蕾缪安's S3 waits with its bullets while nothing is in her range — `kits/ops/chess_char_6_01-lemuen.js`, `render/fx/locks.js`
|
||||
|
||||
- **Seen** (a script on the parent 0255afd: S3 cast with 5 bullets, the locked enemy killed by someone else after 2
|
||||
locks, another enemy alive outside her range): the skill ended at the next lock tick
|
||||
(1.00 s, `skillEnd` reason `ammo`), 3 bullets thrown away, 2 shells; an enemy that came into her range 3 s later found
|
||||
it over. A locked walker leaving her range ended it the same way (4 locks, 1 bullet thrown away). In golden the elite
|
||||
蕾缪安 of roster-018 ended three of her five casts early (2 / 6, 5 / 9 and 6 / 9 bullets left).
|
||||
- **Official**: the skill text 「每0.5秒消耗1发子弹依次锁定敌人……攻击装有5发弹药,打完后结束(可随时停止技能)」: an ammo
|
||||
skill ends when its bullets are spent or when the player stops it. PRTS 卫戍协议/帮助 §作战阶段 技能操作: 「可执行的技能
|
||||
操作包括开启/关闭技能,通常不会自动关闭技能」 — the only automatic close is 玛露希尔's 召唤使魔; 蕾缪安's S3 is on the
|
||||
basic strategy. The client (charpack char_4193_lemuen, battle/buff_template_data.json): the S3 mode's lock is an attack
|
||||
that needs a target (`_minTargetNum` 1, `_allowNoTarget` 0, cooldown `aim_interval`); the skill buff `lemuen_s_3`
|
||||
switches to the S3_End mode (the bombardment) on `ON_BUFF_FINISH` only, and nothing ends it for want of a target. PRTS
|
||||
S3 note: a mark follows its target and stays where the target left.
|
||||
- **Cause**: the kit's lock tick ended the skill when `pickLock` found nobody and anyone had been locked —
|
||||
`if (!e) { if (m.lemLocks.length) skill.end('ammo'); return; }` (chess_char_6_01-lemuen.js:169 on the parent), there
|
||||
since the initial import with no decision behind it.
|
||||
- **Now**: with nothing to lock the skill waits, bullets and locks kept — the marks follow their enemies (out of her range
|
||||
too) or stay where they left — with its lock ready: the next enemy that comes into her range (or is 通缉) is locked on
|
||||
the next tick, then every `aim_interval` s. The skill ends when the bullets are spent and the shells fall on every mark
|
||||
in lock order, as before. While it waits she gains no SP (a running ammo skill holds it, as before); knocked out or
|
||||
withdrawn, no bombardment (unchanged); a battle that ends meanwhile ends without shells (nothing left to hit). The S3
|
||||
`lock` fx carry `hold`: render/fx/locks.js keeps such a reticle while the shooter's view has the skill bit (UF.SKILL)
|
||||
and counts its LOCK_T (5 game s) from the skill's end — without it the reticles faded 5 s into a wait. S2's aim lock
|
||||
(no `hold`) keeps its timeout.
|
||||
- Unchanged and noted: the client lock's 0.1 s pre-delay is not modelled (the lock lands on its tick, as before).
|
||||
- Seen on the way, not changed (S2, not this report): 归乡邀约 spends a bullet on every normal attack (5 of its 6 gone in
|
||||
8 s of attacks on an enemy that is not 通缉), while PRTS's S2 note says only the aimed snipe at a 通缉 target spends one
|
||||
(「若目标为被通缉状态,则攻击改为消耗1发弹药的瞄准狙击,否则不消耗弹药」) — left to the owner: fixed, S2 would hold its
|
||||
buff until 通缉 enemies come, a large change.
|
||||
- Golden: 3 scenarios — traced on both trees with an instrumented copy (SkillRuntime start / end logged, the round's
|
||||
fields and the carried SP); in each the first divergence is an S3 the parent ended with bullets left and nothing in her
|
||||
range:
|
||||
- roster-018: the elite 蕾缪安's first S3 (7.63 s) ended at 9.63 s with 2 of 6 bullets left; now the 6th goes at
|
||||
12.00 s (first differing snapshot window 0–10 s).
|
||||
- boss-boss_3-pair: her second S3 (27.8 s) ended at 30.3 s with 4 of 9 left; now all 9 by 34.43 s (window 30–40 s); the
|
||||
boss now falls at 199.53 s (before: `forced` at the 200 s cap with 145080 HP left).
|
||||
- coop2-NORMAL-14-standins: ai_0's 蕾缪安 (her own kit) — in round 11's battle her S3 ended at 17.2 s (6 of 8 left) and
|
||||
77.97 s (7 of 9); now all bullets are spent and the third cast does not come, so she enters the round's 联防 with
|
||||
25.96 SP instead of 10.27, casts S3 there and kills one more of h_0's leaked enemies: h_0 loses 1 LP less (rounds
|
||||
11–12 LP 18 → 19, 8 → 9; lpLost 30 → 29; ai_0 kills +1, dmgDealt +288).
|
||||
- bonds, standins and diy unchanged.
|
||||
- Tests: `test/sim/feedback5-lemuen-s3-wait.test.js` (3: the killed target and the walker who leaves fail on the parent —
|
||||
the skill ended —; the battle that ends while she waits passes on both), `test/render/fxproj.test.js` +1 (a held lock
|
||||
stays while the shooter's skill bit is on, then LOCK_T after; an unheld one times out — fails on the parent's
|
||||
renderer); `test/content/kits_t6.test.js`, `kits_alt_t6.test.js`, `test/sim/feedback3-ammo-bar.test.js` pass unchanged.
|
||||
@@ -18,7 +18,8 @@
|
||||
// blasts explosions (fireball, flash, shockwave + coloured ground ring, sparks, smoke; heavy ones add debris
|
||||
// and a scorch mark) for blast fx kinds and shell impacts
|
||||
// bombard 蕾缪安 S3: fx 'lock' keeps a reticle on the locked enemy until the 'bombard' of the shell fired at it
|
||||
// (or LOCK_T game s after the shooter's last lock / shell; the S2 aim lock until the snipe's 'crit'); 'bombardShell' = a shell fired now that
|
||||
// (or LOCK_T game s after the shooter's last lock / shell — a held S3 lock, `hold`, LOCK_T after her skill
|
||||
// ends: it waits with its bullets while nothing is in range; the S2 aim lock until the snipe's 'crit'); 'bombardShell' = a shell fired now that
|
||||
// lands on the spot after `t` game s — a launch streak leaves the shooter upwards and the shell drops out
|
||||
// of the sky onto the spot (a long flight climbs out of her first), a closing warning ring marks the spot
|
||||
// meanwhile; 'bombard' is the big explosion at the impact
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
import { SHOT_HEIGHT, bodyZ } from './camera.js';
|
||||
import { FX_KINDS } from './kinds.js';
|
||||
import { easeOut } from './limits.js';
|
||||
import { UF } from '../../../../shared/constants.js';
|
||||
|
||||
/**
|
||||
* Lock reticle: how long (game s) a lock outlives the last sign of its shooter's S3 going on — its latest lock, shell or
|
||||
@@ -18,9 +19,11 @@ export class FxLocks {
|
||||
/**
|
||||
* fx 'lock': a reticle on the locked enemy (following its view; at the last spot once it is gone) until its shell
|
||||
* lands (mortar / _landed) or the aimed shot fires ('crit' from the same shooter); at most LOCK_T game seconds after
|
||||
* the shooter's last lock / shell / bombard (_touchLocks).
|
||||
* the shooter's last lock / shell / bombard (_touchLocks). A held lock (`hold`: 蕾缪安 S3, whose skill waits with its
|
||||
* bullets and locks while nothing is in range) waits as long as its shooter's skill runs (the view's UF.SKILL), its
|
||||
* LOCK_T counted from the skill's end.
|
||||
*/
|
||||
_lock(view, src, x, y, z) {
|
||||
_lock(view, src, x, y, z, hold = false) {
|
||||
let L = this.lockFree.pop();
|
||||
if (!L) {
|
||||
const P = this.P;
|
||||
@@ -34,7 +37,7 @@ export class FxLocks {
|
||||
L = { ring, core };
|
||||
}
|
||||
L.view = view; L.id = view ? view.id : null; L.src = src ?? null; L.x = x; L.y = y; L.z = z;
|
||||
L.t = 0; L.idle = 0; L.max = LOCK_T / this._ts(); L.out = -1; L.shell = false; L.sx = x; L.sy = y;
|
||||
L.t = 0; L.idle = 0; L.max = LOCK_T / this._ts(); L.out = -1; L.shell = false; L.sx = x; L.sy = y; L.hold = !!hold;
|
||||
L.ring.tint = L.core.tint = FX_KINDS.lock.c;
|
||||
L.ring.alpha = L.core.alpha = 0;
|
||||
L.ring.visible = L.core.visible = true;
|
||||
@@ -77,10 +80,12 @@ export class FxLocks {
|
||||
L.t += dt;
|
||||
L.idle += dt;
|
||||
if (L.out < 0 && L.idle >= L.max) L.out = 0;
|
||||
// the shooter knocked out / withdrawn: the sim fires no more shells — only a shell already in the air still lands
|
||||
// the shooter knocked out / withdrawn: the sim fires no more shells — only a shell already in the air still lands;
|
||||
// a held lock waits while its shooter's skill runs (蕾缪安 S3 with nothing in range: its bullets and locks wait)
|
||||
if (L.out < 0 && !L.shell && L.src != null && this.ctx.view) {
|
||||
const sv = this._viewOf(L.src);
|
||||
if (!sv || sv.alive === false) L.out = 0;
|
||||
else if (L.hold && (sv.flags & UF.SKILL)) L.idle = 0;
|
||||
}
|
||||
if (L.out >= 0) { L.out += dt; if (L.out >= LOCK_FADE) { this._freeLock(L); continue; } }
|
||||
const v = L.view;
|
||||
|
||||
@@ -50,7 +50,7 @@ export class FxSim {
|
||||
* counter, dp, coin, crate, down, beam, bolt, strike, volley, pillar, lp, chill, element, flame), except kinds whose
|
||||
* archetype is 'none' (hitCap: a leader hit cancelled by 限伤 draws nothing); unknown kinds get a generic sparkle. `extra` keys used: id (anchor unit — or the shooter of a `pt` kind), r | radius, dur | duration,
|
||||
* t (shell flight, game s), src / from / to / target / targets (unit ids), fx, fy / fromX, fromY / tx, ty (positions),
|
||||
* element, n, scale, kind, tiles.
|
||||
* element, n, scale, kind, tiles, hold ('lock': the reticle waits while the shooter's skill runs).
|
||||
*/
|
||||
simFx(kind, x, y, extra) {
|
||||
const ex = extra && typeof extra === 'object' ? extra : {};
|
||||
@@ -178,9 +178,10 @@ export class FxSim {
|
||||
case 'mark': case 'reticle': {
|
||||
if (kind === 'lock') {
|
||||
// `id` is always the locked enemy: the reticle sticks to its view even a little off the event's spot
|
||||
// (`hold`: 蕾缪安 S3 — the reticle waits while her skill runs, however long nothing is in range)
|
||||
const lv = at.v || this._viewOf(ex.id);
|
||||
this._touchLocks(ex.src ?? null);
|
||||
this._lock(lv, ex.src ?? null, lv ? lv.x : at.x, lv ? lv.y : at.y, lv ? bodyZ(cam, lv, SHOT_HEIGHT.aim) : at.z + 0.55);
|
||||
this._lock(lv, ex.src ?? null, lv ? lv.x : at.x, lv ? lv.y : at.y, lv ? bodyZ(cam, lv, SHOT_HEIGHT.aim) : at.z + 0.55, !!ex.hold);
|
||||
break;
|
||||
}
|
||||
const v = at.v;
|
||||
|
||||
@@ -152,6 +152,14 @@ function lemuen(bb, chess, def) {
|
||||
};
|
||||
return {
|
||||
skills,
|
||||
// S3 礼炮·强制追思, the lock phase: one lock every aim_interval s on an enemy in her range (the least locked first,
|
||||
// then the lowest DEF), one bullet each; the skill ends when the bullets are spent, then bombard. With nothing in
|
||||
// range it waits — bullets and locks kept (the marks follow their enemies / stay where they left) — and locks the
|
||||
// next enemy that comes at once: an ammo skill has no time limit ("攻击装有5发弹药,打完后结束(可随时停止技能)"; in
|
||||
// the client data her S3 lock needs a target and only the spent bullets end the skill buff lemuen_s_3) and the 卫戍协议
|
||||
// automation never stops a skill (PRTS 卫戍协议/帮助 技能操作: "通常不会自动关闭技能"). Until 0.2.0 the skill ended at
|
||||
// the first lock tick with nothing in range (community report: 「蕾缪安3技能范围里没人好像会自动结束」). Its fx 'lock'
|
||||
// carries `hold`: the renderer keeps those reticles up while her skill runs (render/fx/locks.js).
|
||||
skill: {
|
||||
kind: 'ammo',
|
||||
ammo: Math.max(1, Math.floor(num(bb['attack@trigger_time'], 5))),
|
||||
@@ -164,11 +172,11 @@ function lemuen(bb, chess, def) {
|
||||
if (!unit.canAct) return;
|
||||
m.lemAcc += dt;
|
||||
if (m.lemAcc + 1e-9 < aim) return;
|
||||
m.lemAcc -= aim;
|
||||
const e = pickLock(battle, unit, m.lemLocks);
|
||||
if (!e) { if (m.lemLocks.length) skill.end('ammo'); return; }
|
||||
if (!e) { m.lemAcc = aim; return; } // nothing to lock: wait, the next lock ready the moment an enemy comes
|
||||
m.lemAcc -= aim;
|
||||
m.lemLocks.push({ e, x: e.x, y: e.y });
|
||||
battle.fx('lock', { x: e.x, y: e.y, id: e.id, src: unit.id });
|
||||
battle.fx('lock', { x: e.x, y: e.y, id: e.id, src: unit.id, hold: 1 });
|
||||
skill.ammoLeft--;
|
||||
battle.emit('ammoUsed', { unit, left: skill.ammoLeft, skill });
|
||||
if (skill.active && skill.ammoLeft <= 0) skill.end('ammo');
|
||||
|
||||
+51
-53
@@ -224,104 +224,102 @@
|
||||
"round": 14,
|
||||
"seed": 1428555614,
|
||||
"waveId": "act1autochess_h07_03",
|
||||
"time": 200,
|
||||
"ticks": 6000,
|
||||
"reason": "forced",
|
||||
"time": 199.53,
|
||||
"ticks": 5986,
|
||||
"reason": "cleared",
|
||||
"killed": 21,
|
||||
"total": 21,
|
||||
"unspawned": 0,
|
||||
"bossHpLeft": 145080,
|
||||
"bossHpLeft": 0,
|
||||
"rngDraws": 1385,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {
|
||||
"p1": {"killed":21,"total":21,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":1679564,"bossDmg":1583484,"heal":2172,"deaths":0,"layerGains":{}},
|
||||
"p2": {"killed":0,"total":0,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":2359162,"bossDmg":2271437,"heal":16328,"deaths":0,"layerGains":{}}
|
||||
"p1": {"killed":21,"total":21,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":1881663,"bossDmg":1745302,"heal":2230,"deaths":0,"layerGains":{}},
|
||||
"p2": {"killed":0,"total":0,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":2302143,"bossDmg":2254698,"heal":16832,"deaths":0,"layerGains":{}}
|
||||
},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_6_03_b",2,"uniequip_002_yu",3430,1,7,0,0,0,605,0,1],
|
||||
["p1",1,"op","chess_char_6_03_b",2,"uniequip_002_yu",3430,1,7,0,0,0,638,0,1],
|
||||
["p1",2,"op","chess_char_6_06_b",2,"uniequip_002_pepe",2939,1,11,0,0,0,0,0,0],
|
||||
["p1",3,"op","chess_char_6_07_b",2,"uniequip_002_siege2",3101,1,9,0,0,0,0,0,0],
|
||||
["p1",4,"op","chess_char_6_01_b",2,"uniequip_002_lemuen",2131.5,1,13,1,877126,0,0,62,8],
|
||||
["p1",5,"op","chess_char_6_02_b",2,"uniequip_002_sbell2",1933,1,17,0,349841,28,2,63,3],
|
||||
["p1",6,"op","chess_char_6_04_b",2,"uniequip_002_skadi2",1214.37,1,19,1,35820,8433,1241,0,5],
|
||||
["p1",7,"op","chess_char_6_05_b",2,"uniequip_002_pasngr",2307.2,1,21,2,293209,1008,323,97,8],
|
||||
["p1",8,"op","chess_char_6_08_b",2,"uniequip_002_reed2",1668,1,5,1,3064,0,1,11,1],
|
||||
["p1",9,"op","chess_char_6_09_b",0,"uniequip_002_cello",1322,1,15,1,21050,0,0,8,8],
|
||||
["p1",10,"op","chess_char_6_11_b",2,"uniequip_002_mlyss",1893,1,23,0,89834,0,0,206,5],
|
||||
["p1",4,"op","chess_char_6_01_b",2,"uniequip_002_lemuen",2131.5,1,13,2,1071144,0,0,62,8],
|
||||
["p1",5,"op","chess_char_6_02_b",2,"uniequip_002_sbell2",1933,1,17,1,348232,165,10,63,3],
|
||||
["p1",6,"op","chess_char_6_04_b",2,"uniequip_002_skadi2",1214.37,1,19,1,35824,8763,1252,0,5],
|
||||
["p1",7,"op","chess_char_6_05_b",2,"uniequip_002_pasngr",2307.2,1,21,4,284196,1248,326,96,8],
|
||||
["p1",8,"op","chess_char_6_08_b",2,"uniequip_002_reed2",1668,1,5,0,13,0,3,6,1],
|
||||
["p1",9,"op","chess_char_6_09_b",0,"uniequip_002_cello",1322,1,15,1,10883,0,0,7,7],
|
||||
["p1",10,"op","chess_char_6_11_b",2,"uniequip_002_mlyss",1893,1,23,0,88919,0,0,206,5],
|
||||
["p1",11,"token","token_10017_skadi2_dedant",null,null,130.4,0,26,0,0,0,0,0,null],
|
||||
["p2",12,"op","chess_char_6_15_b",2,"uniequip_002_qiubai",3985.92,1,31,6,345376,3222,0,183,3],
|
||||
["p2",13,"op","chess_char_6_19_b",2,"uniequip_002_blkkgt",2767,1,12,1,27218,0,0,6,1],
|
||||
["p2",12,"op","chess_char_6_15_b",2,"uniequip_002_qiubai",3985.92,1,31,3,358064,3029,0,188,3],
|
||||
["p2",13,"op","chess_char_6_19_b",2,"uniequip_002_blkkgt",2767,1,12,0,5,0,0,0,1],
|
||||
["p2",14,"op","chess_char_5_01_b",1,"uniequip_002_excu2",2314,1,10,0,0,0,0,0,0],
|
||||
["p2",15,"op","chess_char_6_17_b",2,"uniequip_002_nearl2",6215.89,1,46,0,293226,0,0,85,4],
|
||||
["p2",16,"op","chess_char_6_12_b",1,"uniequip_002_rosmon",3117.74,1,16,2,189809,0,0,74,4],
|
||||
["p2",17,"op","chess_char_6_13_b",1,"uniequip_002_angel2",2392.2,1,20,3,1205701,5257,423,365,6],
|
||||
["p2",18,"op","chess_char_6_14_b",2,"uniequip_002_lumen",2050.92,1,22,0,0,0,2846,42,1],
|
||||
["p2",19,"op","chess_char_6_16_b",2,"uniequip_002_halo2",1554.12,1,25,0,87945,932,0,163,4],
|
||||
["p2",20,"op","chess_char_6_18_b",2,"uniequip_002_whitw2",1541,1,6,3,182528,0,0,13,3],
|
||||
["p2",21,"op","chess_char_6_20_b",2,"uniequip_002_agoat2",1631.88,1,18,0,0,0,13059,42,2],
|
||||
["p2",15,"op","chess_char_6_17_b",2,"uniequip_002_nearl2",6215.89,1,48,0,280519,0,0,81,4],
|
||||
["p2",16,"op","chess_char_6_12_b",1,"uniequip_002_rosmon",3117.74,1,16,2,186844,0,0,74,4],
|
||||
["p2",17,"op","chess_char_6_13_b",1,"uniequip_002_angel2",2392.2,1,20,4,1216961,5257,494,363,6],
|
||||
["p2",18,"op","chess_char_6_14_b",2,"uniequip_002_lumen",2050.92,1,22,0,0,0,2448,44,1],
|
||||
["p2",19,"op","chess_char_6_16_b",2,"uniequip_002_halo2",1554.12,1,25,0,86149,981,0,163,4],
|
||||
["p2",20,"op","chess_char_6_18_b",2,"uniequip_002_whitw2",1541,1,6,4,173602,0,0,5,3],
|
||||
["p2",21,"op","chess_char_6_20_b",2,"uniequip_002_agoat2",1631.88,1,18,0,0,0,13890,48,2],
|
||||
["-","~1","device","trap_1105_accrate",null,null,100,1,1,0,0,0,0,0,null],
|
||||
["-","~2","device","trap_1105_accrate",null,null,100,1,2,0,0,0,0,0,null],
|
||||
["-","~3","device","trap_1105_accrate",null,null,100,1,3,0,0,0,0,0,null],
|
||||
["-","~4","device","trap_1105_accrate",null,null,100,1,4,0,0,0,0,0,null],
|
||||
["p1","~1","token","token_10030_mlyss_wtrman",null,null,0,0,24,0,8947,1880,0,18,1],
|
||||
["p1","~2","token","token_10030_mlyss_wtrman",null,null,860.02,0,41,0,674,1020,0,1,null],
|
||||
["p1","~1","token","token_10017_skadi2_dedant",null,null,100,0,48,0,0,0,0,0,null],
|
||||
["p2","~1","token","token_10019_nearl2_sword",null,null,6480,0,50,0,9120,0,0,0,null],
|
||||
["p1","~1","token","token_10030_mlyss_wtrman",null,null,1557.36,1,24,0,42452,0,0,90,1],
|
||||
["p1","~2","token","token_10030_mlyss_wtrman",null,null,1880.37,0,41,0,0,0,0,0,null],
|
||||
["p1","~1","token","token_10017_skadi2_dedant",null,null,100,0,49,0,0,0,0,0,null],
|
||||
["p2","~1","token","token_10019_nearl2_sword",null,null,6480,0,50,0,0,0,0,0,null],
|
||||
["p1","~2","token","token_10017_skadi2_dedant",null,null,130.4,0,53,0,0,0,0,0,null],
|
||||
["p2","~2","token","token_10019_nearl2_sword",null,null,6480,0,55,0,9120,0,0,0,null],
|
||||
["p1","~3","token","token_10017_skadi2_dedant",null,null,100,0,57,0,0,0,0,0,null],
|
||||
["p2","~3","token","token_10019_nearl2_sword",null,null,6480,1,60,0,9120,0,0,0,null]
|
||||
["p2","~2","token","token_10019_nearl2_sword",null,null,6480,0,55,0,0,0,0,0,null],
|
||||
["p1","~3","token","token_10017_skadi2_dedant",null,null,100,0,58,0,0,0,0,0,null],
|
||||
["p2","~3","token","token_10019_nearl2_sword",null,null,6480,1,60,0,0,0,0,0,null]
|
||||
],
|
||||
"enemies": {
|
||||
"enemy_1197_sfshu_2": [2,2,0,0,28809],
|
||||
"enemy_1198_msfshu_2": [6,6,0,0,24],
|
||||
"enemy_1209_sfden_2": [2,2,0,2901,154793],
|
||||
"enemy_1209_sfden_2": [2,2,0,0,154793],
|
||||
"enemy_1210_msfden_2": [2,2,0,0,90],
|
||||
"enemy_9021_acduml": [1,0,0,0,3854920],
|
||||
"enemy_9023_acdums": [9,9,0,5690,90]
|
||||
"enemy_9021_acduml": [1,1,0,0,4000000],
|
||||
"enemy_9023_acdums": [9,9,0,6252,90]
|
||||
},
|
||||
"hooks": [1,58,6000,1444,1444,3043,3408,2091,22,32,68,62,368,46997,1655,3,22,0,1,22,0,2,0],
|
||||
"events": {"atk":1595,"deploy":32,"die":32,"dmg":3120,"engage":15,"fx":1016,"heal":279,"skill":130,"spawn":55,"status":506},
|
||||
"hooks": [1,58,5986,1498,1498,3074,3446,2102,22,32,67,60,370,46778,1625,2,22,0,1,21,0,2,0],
|
||||
"events": {"atk":1634,"deploy":32,"die":32,"dmg":3158,"engage":13,"fx":1025,"heal":282,"skill":127,"spawn":55,"status":511},
|
||||
"fx": {
|
||||
"airstrike": 121,
|
||||
"appear": 1,
|
||||
"airstrike": 130,
|
||||
"beam": 9,
|
||||
"blink": 3,
|
||||
"bombard": 65,
|
||||
"bombardShell": 65,
|
||||
"bombard": 69,
|
||||
"bombardShell": 69,
|
||||
"buff": 3,
|
||||
"burst": 2,
|
||||
"copy": 1,
|
||||
"disappear": 1,
|
||||
"displace": 3,
|
||||
"displace": 1,
|
||||
"dp": 5,
|
||||
"drone": 338,
|
||||
"droneLock": 16,
|
||||
"drone": 337,
|
||||
"droneLock": 17,
|
||||
"drones": 3,
|
||||
"explode": 132,
|
||||
"explode": 133,
|
||||
"finale": 1,
|
||||
"firewall": 1,
|
||||
"garrisonGrant": 1,
|
||||
"lightning": 73,
|
||||
"link": 6,
|
||||
"lock": 65,
|
||||
"lightning": 76,
|
||||
"link": 4,
|
||||
"lock": 69,
|
||||
"lure": 3,
|
||||
"phase": 18,
|
||||
"radiantSword": 3,
|
||||
"scorchBurst": 2,
|
||||
"slash": 11,
|
||||
"snow": 16,
|
||||
"scorchBurst": 1,
|
||||
"slash": 5,
|
||||
"snow": 15,
|
||||
"split": 1,
|
||||
"steal": 6,
|
||||
"storm": 8,
|
||||
"summon": 14,
|
||||
"sunBurst": 3,
|
||||
"talent": 4,
|
||||
"telegraph": 4,
|
||||
"telegraph": 3,
|
||||
"tide": 5,
|
||||
"wanted": 3
|
||||
"wanted": 2
|
||||
},
|
||||
"snaps": "4c79f145 ebcda26d 068f0e59 260d03ab 4d134b3f 74d79bd3 96b17d7f aa35887e 6f63c25c 204e2f98 9ab4f3f0 f9ac2510 13eb96e3 7db1e342 0bf684aa 45383cbf d2edb802 be365f88 86b51adc d438ceb4"
|
||||
"snaps": "4c79f145 ebcda26d 068f0e59 f77a47b8 1b3b0779 8e1af8f0 1007ce9e d942d746 2f1bb88d ece27d81 47c5042c 2a8ee6a5 39f34644 5c84574d dd568842 0b4a024a 5841ee36 0333ed5c df19d0bf fd9c01b0"
|
||||
},
|
||||
"boss-boss_3-solo": {
|
||||
"about": "假想敌:管 solo pool 2000000: chess_char_5_08_b chess_char_5_11_b chess_char_5_05_b chess_char_5_06_b chess_char_5_13_b chess_char_5_07_b chess_char_5_02_b chess_char_5_03_b chess_char_5_10_b chess_char_5_12_b",
|
||||
|
||||
@@ -1559,12 +1559,12 @@
|
||||
},
|
||||
{
|
||||
"round": 11,
|
||||
"h_0": [1,18,12,0,2,5,8,"def68119",93,"arcaneShip 1/15, kazimierzShip 0/8, miraShip 1/0, preciShip 1/26, siracusaShip 1/18, soloShip 1/0, suntShip 1/0, swiftShip 1/34, yanShip 0/13",21,25,4,102],
|
||||
"h_0": [1,19,12,0,2,5,8,"def68119",93,"arcaneShip 1/15, kazimierzShip 0/8, miraShip 1/0, preciShip 1/26, siracusaShip 1/18, soloShip 1/0, suntShip 1/0, swiftShip 1/34, yanShip 0/13",21,25,4,102],
|
||||
"ai_0": [1,23,13,0,0,5,8,"c0b11e3b",224,"arcaneShip 0/2, deputShip 1/30, kazimierzShip 0/8, lateranoShip 1/39, miraShip 1/4, preciShip 0/2, raidShip 0/2, sargonShip 0/2, siracusaShip 1/40, skillfulShip 1/52, suntShip 1/12, swiftShip 1/47",25,25,0,98]
|
||||
},
|
||||
{
|
||||
"round": 12,
|
||||
"h_0": [1,8,14,0,0,6,8,"13e7bef4",103,"arcaneShip 1/15, kazimierzShip 0/8, miraShip 1/0, preciShip 1/31, siracusaShip 1/18, suntShip 1/0, swiftShip 1/39, yanShip 0/13",18,31,13,117],
|
||||
"h_0": [1,9,14,0,0,6,8,"13e7bef4",103,"arcaneShip 1/15, kazimierzShip 0/8, miraShip 1/0, preciShip 1/31, siracusaShip 1/18, suntShip 1/0, swiftShip 1/39, yanShip 0/13",18,31,13,117],
|
||||
"ai_0": [1,22,12,0,1,6,8,"defd2806",262,"arcaneShip 0/2, deputShip 1/32, kazimierzShip 0/8, lateranoShip 1/57, miraShip 1/6, preciShip 0/2, raidShip 0/2, sargonShip 0/2, siracusaShip 1/42, skillfulShip 1/62, suntShip 1/14, swiftShip 1/49",30,31,1,112]
|
||||
},
|
||||
{
|
||||
@@ -1584,7 +1584,7 @@
|
||||
"title": {"id":"comment_6","name":"挥金如土","picId":"comment_icon_6","text":"消耗资金最多"},
|
||||
"trophies": 3,
|
||||
"reward": 280,
|
||||
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":2083752,"gold":129,"itemsEquipped":15,"kills":231,"leaks":63,"lpLost":30,"merges":4,"perfectRounds":8,"refreshes":22},
|
||||
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":2083752,"gold":129,"itemsEquipped":15,"kills":231,"leaks":63,"lpLost":29,"merges":4,"perfectRounds":8,"refreshes":22},
|
||||
"lineup": [],
|
||||
"bonds": ["arcaneShip 0/21","kazimierzShip 0/8","preciShip 0/42","raidShip 0/16","siracusaShip 0/30","swiftShip 0/44","yanShip 0/13"]
|
||||
},
|
||||
@@ -1598,7 +1598,7 @@
|
||||
"title": {"id":"comment_1","name":"卫戍之星","picId":"comment_icon_1","text":"对敌方领袖造成伤害最高(仅胜利时)"},
|
||||
"trophies": 4,
|
||||
"reward": 400,
|
||||
"stats": {"activatedLayers":336,"bossDamage":390000,"dmgDealt":2919224,"gold":141,"itemsEquipped":23,"kills":258,"leaks":41,"lpLost":11,"merges":8,"perfectRounds":11,"refreshes":27},
|
||||
"stats": {"activatedLayers":336,"bossDamage":390000,"dmgDealt":2919512,"gold":141,"itemsEquipped":23,"kills":259,"leaks":41,"lpLost":11,"merges":8,"perfectRounds":11,"refreshes":27},
|
||||
"lineup": ["4_21_a@12,3","5_20_a@12,7","3_21_b@11,3[1_05_e_b+3_01_e_b]","6_05_a@11,8","3_01_b@10,3[1_01_e_a+6_05_e_a]","3_18_b@10,7[4_02_e_a+4_11_e_a]","4_16_b@10,8[4_10_e_a+4_04_e_a]","6_01_a@9,8[2_01_e_a+1_02_e_a]"],
|
||||
"bonds": ["arcaneShip 0/2","deputShip 0/32","kazimierzShip 0/8","lateranoShip 1/83","miraShip 1/12","preciShip 1/2","raidShip 0/2","sargonShip 0/2","siracusaShip 1/84","skillfulShip 1/74","suntShip 1/14","swiftShip 1/67"]
|
||||
}
|
||||
|
||||
+34
-36
@@ -1129,14 +1129,14 @@
|
||||
"round": 13,
|
||||
"seed": 264387324,
|
||||
"waveId": "act1autochess_h06",
|
||||
"time": 195,
|
||||
"ticks": 5850,
|
||||
"time": 194.97,
|
||||
"ticks": 5849,
|
||||
"reason": "cleared",
|
||||
"killed": 120,
|
||||
"total": 120,
|
||||
"unspawned": 0,
|
||||
"bossHpLeft": null,
|
||||
"rngDraws": 549,
|
||||
"rngDraws": 490,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {
|
||||
"p1": {
|
||||
@@ -1146,64 +1146,62 @@
|
||||
"leaks": 0,
|
||||
"leaksUncounted": 0,
|
||||
"coins": 12,
|
||||
"dmg": 1634623,
|
||||
"dmg": 1565127,
|
||||
"bossDmg": 0,
|
||||
"heal": 33055,
|
||||
"heal": 31396,
|
||||
"deaths": 1,
|
||||
"layerGains": {"lateranoShip":8,"preciShip":8,"sargonShip":23}
|
||||
"layerGains": {"lateranoShip":12,"preciShip":12,"sargonShip":26}
|
||||
}
|
||||
},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_6_03_b",2,"uniequip_002_yu",3430,1,3,0,0,0,1317,0,1],
|
||||
["p1",2,"op","chess_char_6_06_b",2,"uniequip_002_pepe",2939,1,6,0,0,0,0,0,0],
|
||||
["p1",3,"op","chess_char_6_07_b",2,"uniequip_002_siege2",3287.06,1,9,0,6177,1792,0,2,1],
|
||||
["p1",4,"op","chess_char_6_20_a",2,null,1311.22,1,4,0,0,0,22720,45,1],
|
||||
["p1",5,"op","chess_char_6_01_b",2,"uniequip_002_lemuen",1558.2,1,7,12,177469,0,0,23,5],
|
||||
["p1",6,"op","chess_char_6_02_b",2,"uniequip_002_sbell2",3981.98,1,10,8,54371,1751,197,11,2],
|
||||
["p1",7,"op","chess_char_6_04_b",2,"uniequip_002_skadi2",1693.88,1,13,4,48553,8129,105,0,5],
|
||||
["p1",8,"op","chess_char_6_05_b",2,"uniequip_002_pasngr",0,0,15,20,243670,11371,3228,39,7],
|
||||
["p1",9,"op","chess_char_6_08_b",2,"uniequip_002_reed2",1768.08,1,5,2,78780,0,2839,18,2],
|
||||
["p1",10,"op","chess_char_6_09_b",0,"uniequip_002_cello",1401.32,1,8,2,28299,0,0,12,13],
|
||||
["p1",11,"op","chess_char_6_11_b",2,"uniequip_002_mlyss",2006.58,1,11,18,153886,2952,641,152,5],
|
||||
["p1",12,"op","chess_char_6_12_b",1,"uniequip_002_rosmon",4214.73,1,14,48,795747,7667,1111,70,4],
|
||||
["p1",1,"op","chess_char_6_03_b",2,"uniequip_002_yu",4026.82,1,3,0,0,0,0,0,0],
|
||||
["p1",2,"op","chess_char_6_06_b",2,"uniequip_002_pepe",3450.39,1,6,0,0,0,0,0,0],
|
||||
["p1",3,"op","chess_char_6_07_b",2,"uniequip_002_siege2",3640.57,1,9,0,0,0,0,0,0],
|
||||
["p1",4,"op","chess_char_6_20_a",2,null,1452.24,1,4,0,0,0,22245,41,2],
|
||||
["p1",5,"op","chess_char_6_01_b",2,"uniequip_002_lemuen",1725.78,1,7,9,194843,0,0,18,5],
|
||||
["p1",6,"op","chess_char_6_02_b",2,"uniequip_002_sbell2",4202.34,1,10,4,49828,1259,566,10,2],
|
||||
["p1",7,"op","chess_char_6_04_b",2,"uniequip_002_skadi2",1876.05,1,13,2,30324,9629,331,0,4],
|
||||
["p1",8,"op","chess_char_6_05_b",2,"uniequip_002_pasngr",0,0,15,18,231847,10065,3224,37,7],
|
||||
["p1",9,"op","chess_char_6_08_b",2,"uniequip_002_reed2",1958.23,1,5,4,57431,0,1066,8,1],
|
||||
["p1",10,"op","chess_char_6_09_b",0,"uniequip_002_cello",1552.03,1,8,0,9057,0,0,6,6],
|
||||
["p1",11,"op","chess_char_6_11_b",2,"uniequip_002_mlyss",2222.38,1,11,20,158083,1500,152,153,4],
|
||||
["p1",12,"op","chess_char_6_12_b",1,"uniequip_002_rosmon",4659.3,1,14,55,762444,7150,658,73,4],
|
||||
["p1",13,"token","token_10017_skadi2_dedant",null,null,100,0,16,0,0,0,0,0,null],
|
||||
["p1",14,"token","token_10030_mlyss_wtrman",null,null,0,0,12,3,14239,2620,0,38,1],
|
||||
["p1",14,"token","token_10030_mlyss_wtrman",null,null,2420.79,1,12,6,41576,2426,0,89,1],
|
||||
["-","~1","device","trap_1105_accrate",null,null,100,1,1,0,0,0,0,0,null],
|
||||
["-","~2","device","trap_1105_accrate",null,null,100,1,2,0,0,0,0,0,null],
|
||||
["p1","~1","token","token_10030_mlyss_wtrman",null,null,0,0,37,0,4916,2245,59,5,null],
|
||||
["p1","~2","token","token_10030_mlyss_wtrman",null,null,0,0,52,0,640,2810,389,5,null],
|
||||
["p1","~1","token","token_10030_mlyss_wtrman",null,null,0,0,37,0,5009,2915,729,10,null],
|
||||
["p1","~2","token","token_10030_mlyss_wtrman",null,null,0,0,52,0,512,2733,355,4,null],
|
||||
["p1","~1","token","token_10017_skadi2_dedant",null,null,117.4,0,60,0,0,0,0,0,null],
|
||||
["p1","~3","token","token_10030_mlyss_wtrman",null,null,0,0,69,0,1028,2421,0,3,null],
|
||||
["p1","~1","token","token_10040_siege2_vlion",null,null,4240,0,100,0,475,0,0,1,null],
|
||||
["p1","~3","token","token_10030_mlyss_wtrman",null,null,1313.01,0,71,1,9719,1878,770,12,null],
|
||||
["p1","~4","token","token_10030_mlyss_wtrman",null,null,1405.84,0,100,1,5828,1493,713,12,null],
|
||||
["p1","~2","token","token_10017_skadi2_dedant",null,null,100,0,102,0,0,0,0,0,null],
|
||||
["p1","~4","token","token_10030_mlyss_wtrman",null,null,2185.72,1,121,3,15883,0,0,30,1],
|
||||
["p1","~5","token","token_10030_mlyss_wtrman",null,null,2137.36,0,133,2,9943,498,449,12,null],
|
||||
["p1","~3","token","token_10017_skadi2_dedant",null,null,100,1,139,0,0,0,0,0,null],
|
||||
["p1","~6","token","token_10030_mlyss_wtrman",null,null,2062,1,150,0,548,0,0,1,null]
|
||||
["p1","~5","token","token_10030_mlyss_wtrman",null,null,1054.21,0,132,2,8626,1773,586,12,null],
|
||||
["p1","~3","token","token_10017_skadi2_dedant",null,null,117.4,1,138,0,0,0,0,0,null]
|
||||
],
|
||||
"enemies": {
|
||||
"enemy_1005_yokai": [1,1,0,0,1327],
|
||||
"enemy_1009_lurker": [1,1,0,0,3650],
|
||||
"enemy_1023_jmage": [1,1,0,697,3650],
|
||||
"enemy_1092_mdgint": [1,1,0,1156,165888],
|
||||
"enemy_1092_mdgint": [1,1,0,1397,165888],
|
||||
"enemy_1166_dusbr": [1,1,0,0,4977],
|
||||
"enemy_1197_sfshu_2": [1,1,0,0,5557],
|
||||
"enemy_1198_msfshu_2": [3,3,0,0,12],
|
||||
"enemy_1210_msfden_2": [1,1,0,0,45],
|
||||
"enemy_1229_darmy": [27,27,0,0,188117],
|
||||
"enemy_1229_darmy_2": [57,57,0,0,520059],
|
||||
"enemy_1275_dwlock_2": [21,21,0,18938,487711],
|
||||
"enemy_1283_sgkill": [1,1,0,2701,19907],
|
||||
"enemy_1364_spnaxe_2": [1,1,0,4260,135851],
|
||||
"enemy_1275_dwlock_2": [21,21,0,27266,487711],
|
||||
"enemy_1283_sgkill": [1,1,0,2984,19907],
|
||||
"enemy_1364_spnaxe_2": [1,1,0,1086,66355],
|
||||
"enemy_1367_dseed": [2,2,0,0,9953],
|
||||
"enemy_1439_dslntf": [1,1,0,0,49766],
|
||||
"enemy_2002_bearmi_2": [1,1,0,0,18248],
|
||||
"enemy_9008_acbunn": [1,1,0,9545,19907]
|
||||
"enemy_9008_acbunn": [1,1,0,2434,19907]
|
||||
},
|
||||
"hooks": [1,148,5850,530,530,1385,1542,3782,127,132,48,43,27,29676,402,6,122,0,1,127,8,6,0],
|
||||
"events": {"atk":636,"bounty":6,"deploy":24,"die":132,"dmg":1462,"engage":16,"fx":258,"heal":231,"layer":8,"skill":91,"spawn":148,"status":437},
|
||||
"fx": {"beam":5,"bombard":27,"bombardShell":27,"burst":6,"camouflage":2,"copy":2,"dp":5,"firewall":1,"garrison":6,"lightning":97,"link":1,"lock":27,"lure":2,"scorchBurst":11,"snow":12,"spGain":2,"split":5,"storm":7,"summon":3,"talent":1,"tide":5,"wanted":4},
|
||||
"snaps": "9cdb845f 1a3da81a b8f8fa18 18adb6a1 045ac790 92daeb67 b8964a05 72d66b06 7650d4e4 fac284c3 d14f07dd e93511be da2827c7 b87b3885 004babab e8850449 0fff5530 45bf7443 2e7fa788 2015799d"
|
||||
"hooks": [1,146,5849,541,541,1343,1500,4125,125,131,36,32,37,24823,332,7,122,0,1,125,11,8,0],
|
||||
"events": {"atk":632,"bounty":6,"deploy":22,"die":131,"dmg":1420,"engage":13,"fx":271,"heal":198,"layer":11,"skill":68,"spawn":146,"status":377},
|
||||
"fx": {"beam":6,"bombard":31,"bombardShell":31,"burst":8,"camouflage":2,"copy":1,"dp":4,"explode":1,"garrison":8,"lightning":98,"link":1,"lock":37,"lure":2,"scorchBurst":13,"snow":7,"split":5,"storm":7,"summon":2,"talent":1,"tide":4,"wanted":2},
|
||||
"snaps": "462bd251 0720b450 e6cc2e2b e9020690 49bdb529 f3e5da0b 9e37e4e7 1f15c3ae 4e3f15d4 2dfffd4f 241bcf3a f616e60d 30648a5c 32b08230 6b3af4f0 8f125452 d62f0b43 82439da4 0cca37a4 0eb827d6"
|
||||
},
|
||||
"roster-019": {
|
||||
"about": "pass 0 band 7: chess_char_6_15_b chess_char_6_19_b chess_char_5_01_b chess_char_5_05_b chess_char_6_17_b chess_char_6_13_b chess_char_6_14_b chess_char_6_16_b chess_char_6_18_b chess_char_6_20_b chess_char_5_02_b chess_char_5_03_b",
|
||||
|
||||
@@ -18,6 +18,7 @@ import * as SIM from '../../server/sim/constants.js';
|
||||
import { installFakePixi, fakeViewCtx } from './fakepixi.js';
|
||||
import { presetCamera } from '../../public/js/render/projection.js';
|
||||
import { PROJ, HIT_TINT } from '../../public/js/render/style.js';
|
||||
import { UF } from '../../shared/constants.js';
|
||||
|
||||
let fake, FX, T;
|
||||
before(async () => {
|
||||
@@ -354,6 +355,23 @@ describe('蕾缪安 S3: lock, bombardShell, bombard', () => {
|
||||
assert.equal(fx.locks.length, 0);
|
||||
});
|
||||
|
||||
test('a held S3 lock (fx `hold`) waits as long as her skill runs with nothing in range, then LOCK_T after it ends; an unheld lock still times out', () => {
|
||||
// 0.2.0 community report: S3 no longer ends by itself with nothing in her range — it waits with its bullets and locks
|
||||
const { fx, lem } = setup();
|
||||
lem.flags = UF.SKILL; // her S3 runs (the snapshot's skill bit)
|
||||
fx.simFx('lock', 8, 10, { id: 21, src: 1, hold: 1 });
|
||||
fx.simFx('lock', 9, 11.5, { id: 23, src: 1 }); // an S2 aim lock: no hold
|
||||
const [held, plain] = fx.locks;
|
||||
run(fx, 20 / 2); // 20 game s at 2×, nothing new from her
|
||||
assert.ok(fx.locks.includes(held) && held.out < 0, 'the held reticle stays while her skill waits');
|
||||
assert.ok(!fx.locks.includes(plain), 'the unheld one timed out after LOCK_T');
|
||||
lem.flags = 0; // the skill ended
|
||||
run(fx, 4 / 2);
|
||||
assert.ok(held.out < 0, 'LOCK_T counts from the skill end');
|
||||
run(fx, 1 / 2 + 0.3);
|
||||
assert.equal(fx.locks.length, 0, 'gone LOCK_T after the skill ended (no shell came)');
|
||||
});
|
||||
|
||||
test('a lock sticks to the enemy named in `id` even when its view is a little off the event spot', () => {
|
||||
const { fx, e1 } = setup();
|
||||
fx.simFx('lock', 9, 10, { id: 21, src: 1 }); // e1 drawn at (8, 10): a fast walker between snapshots
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
// Community report (0.2.0, relayed by the owner): 「蕾缪安3技能范围里没人好像会自动结束」 — 蕾缪安's S3 礼炮·强制追思 ended by
|
||||
// itself when nothing was left in her range. The kit ended the skill at the first lock tick with no enemy to lock (once
|
||||
// it had locked one), so the bombardment fell at once and the bullets left were thrown away. Official: an ammo skill
|
||||
// ends when its bullets are spent ("攻击装有5发弹药,打完后结束(可随时停止技能)"); in the client data her S3 lock needs a
|
||||
// target and only the spent bullets end the skill buff (lemuen_s_3 → the S3_End bombardment mode); the 卫戍协议
|
||||
// automation never stops a skill (PRTS 卫戍协议/帮助 技能操作: "通常不会自动关闭技能"). Now the skill waits — bullets and
|
||||
// locks kept, the marks following their enemies — and locks the next enemy that comes into her range at once.
|
||||
//
|
||||
// Flat stage: 蕾缪安 on (10,3) faces right — her 3-9 range covers cols 3–7 on her row, 3–6 one row off, 3–5 two rows off.
|
||||
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { makeBattle, enemyRec, checkInvariants } from '../helpers/battleHarness.js';
|
||||
|
||||
const LEM = 'chess_char_6_01_a';
|
||||
const dummy = (key) => enemyRec({ key, hp: 1e7, speed: 0 });
|
||||
const DEFS = {
|
||||
enemies: {
|
||||
enemy_dummy: dummy('enemy_dummy'), enemy_far: dummy('enemy_far'), enemy_late: dummy('enemy_late'),
|
||||
enemy_walker: enemyRec({ key: 'enemy_walker', hp: 1e7, speed: 1.5 }),
|
||||
},
|
||||
};
|
||||
|
||||
/** 蕾缪安 with a full S3 at once (the harness has no battle-start operation cooldown); h.dmg / h.locks / h.shells logs. */
|
||||
function lemuen(enemies, opts = {}) {
|
||||
const dmg = [], ends = [];
|
||||
const h = makeBattle({
|
||||
defs: DEFS, seed: 7, timeLimit: 200, units: [{ chessId: LEM, row: 10, col: 3, carryState: { sp: 99 } }], enemies,
|
||||
hooks: ['skillStart', 'skillEnd', 'ammoUsed'], ...opts,
|
||||
setup(b) {
|
||||
b.on('damaged', (c) => dmg.push({ src: c.source?.id ?? null, tgt: c.target.id, tags: c.dmg?.tags ?? [], t: b.time }), { priority: -999 });
|
||||
b.on('skillEnd', ({ unit, reason }) => { if (unit.defId === LEM) ends.push({ reason, t: b.time }); });
|
||||
},
|
||||
});
|
||||
const u = h.unit(LEM);
|
||||
const fxOf = (kind) => h.eventsOf('fx').filter((e) => e[1] === kind).map((e) => ({ x: e[2], y: e[3], t: e[4]?.t, ...e[4] }));
|
||||
return { h, u, dmg, ends, locks: () => fxOf('lock'), shells: () => fxOf('bombardShell'), bombs: () => dmg.filter((d) => d.src === u.id && d.tags.includes('bombard')) };
|
||||
}
|
||||
const inRange = (h, u) => h.b.enemiesInKeys(u.rangeKeys, u, u.profile);
|
||||
|
||||
test('the locked enemy dies and nothing else is in her range: S3 keeps running with its bullets and locks — no early bombardment', () => {
|
||||
const { h, u, ends, locks, shells, bombs } = lemuen([{ key: 'enemy_dummy', pos: [10, 5] }, { key: 'enemy_far', pos: [10, 9] }]);
|
||||
assert.ok(h.runUntil(() => u.skill.active, 5), 'S3 cast');
|
||||
const full = u.skill.ammoMax;
|
||||
assert.ok(h.runUntil(() => u.skill.ammoLeft === full - 2, 5), 'two locks');
|
||||
h.b.kill(h.enemy('enemy_dummy'));
|
||||
assert.equal(inRange(h, u).length, 0, 'nothing left in her range (enemy_far on (10,9) is out of it)');
|
||||
h.run(10);
|
||||
assert.equal(u.skill.active, true, 'the skill waits (the report: it ended by itself)');
|
||||
assert.deepEqual(ends, [], 'no skill end');
|
||||
assert.equal(u.skill.ammoLeft, full - 2, 'the bullets left are kept');
|
||||
assert.equal(locks().length, 2, 'no new lock without a target');
|
||||
assert.equal(shells().length, 0, 'no shell before the skill ends');
|
||||
assert.equal(bombs().length, 0, 'no bombardment');
|
||||
assert.equal(u.skill.sp, 0, 'no SP while the ammo skill runs');
|
||||
assert.equal(u.mem.lemLocks.length, 2, 'the locks are kept');
|
||||
assert.ok(locks().every((l) => l.hold === 1), 'fx lock `hold`: the renderer keeps these reticles up while her skill runs');
|
||||
checkInvariants(h.b);
|
||||
});
|
||||
|
||||
test('a locked walker leaves her range: the skill waits; the next enemy that comes is locked at once, and the spent bullets bomb every mark — the walker where it is now', () => {
|
||||
const { h, u, ends, locks, shells, bombs, dmg } = lemuen([{ key: 'enemy_walker', route: { motion: 'WALK', start: [9, 5], end: [9, 10], checkpoints: [] } }]);
|
||||
assert.ok(h.runUntil(() => u.skill.active, 5), 'S3 cast');
|
||||
const walker = h.enemy('enemy_walker');
|
||||
const full = u.skill.ammoMax;
|
||||
assert.ok(h.runUntil(() => inRange(h, u).length === 0, 10), 'the walker walks out of her range');
|
||||
const left = u.skill.ammoLeft;
|
||||
assert.ok(left > 0 && left < full, `locked it ${full - left} times, ${left} bullet(s) left`);
|
||||
h.run(3);
|
||||
assert.equal(u.skill.active, true, 'S3 waits with nothing in range');
|
||||
assert.equal(u.skill.ammoLeft, left, 'bullets kept');
|
||||
assert.ok(walker.alive && inRange(h, u).length === 0, 'the walker is still out of her range');
|
||||
// the next enemy in range is locked the moment it comes (her lock is ready), every 0.5 s after that
|
||||
const late = h.spawn('enemy_late', { pos: [10, 6] });
|
||||
const t0 = h.b.time;
|
||||
h.step();
|
||||
const first = locks().find((l) => l.id === late.id);
|
||||
assert.ok(first, 'the newcomer is locked on the next tick');
|
||||
assert.ok(h.runUntil(() => !u.skill.active, 10), 'the skill ends once the bullets are spent');
|
||||
assert.deepEqual(ends.map((e) => e.reason), ['ammo']);
|
||||
assert.equal(h.hooksOf('ammoUsed').filter((c) => c.unit === u).length, full, 'every bullet spent on a lock');
|
||||
assert.ok(h.b.time - t0 <= (left - 1) * u.def.skill.bb['attack@aim_interval'] + 0.1, 'the newcomer took the bullets left, 0.5 s apart');
|
||||
// the shells follow in lock order: the walker's marks first (it is followed out of her range), then the newcomer's
|
||||
const walkerLocks = full - left;
|
||||
h.run(0.3 * (full + 2));
|
||||
const s = shells();
|
||||
assert.equal(s.length, full, 'one shell per lock');
|
||||
const spread = u.def.skill.bb['attack@emit_offset'] + 0.01;
|
||||
for (let i = 0; i < walkerLocks; i++) assert.ok(s[i].x > 6.5, `shell ${i} falls on the walker out of her range (x ${s[i].x.toFixed(2)})`);
|
||||
for (let i = walkerLocks; i < full; i++) assert.ok(Math.abs(s[i].x - 6) <= spread && Math.abs(s[i].y - 10) <= spread, `shell ${i} on the newcomer`);
|
||||
assert.equal(bombs().filter((d) => d.tgt === walker.id).length, walkerLocks, 'the walker is hit by its own shells only');
|
||||
assert.equal(bombs().filter((d) => d.tgt === late.id).length, left, 'the newcomer by its own');
|
||||
assert.equal(dmg.filter((d) => d.src === u.id && !d.tags.includes('bombard') && d.t < ends[0].t).length, 0, 'no normal attack during S3');
|
||||
checkInvariants(h.b);
|
||||
});
|
||||
|
||||
test('the last enemy dies while she waits: the battle ends cleared, nothing more to bomb, no error', () => {
|
||||
const { h, u, shells } = lemuen([{ key: 'enemy_dummy', pos: [10, 5] }]);
|
||||
assert.ok(h.runUntil(() => u.skill.active && u.mem.lemLocks?.length === 2, 5), 'two locks');
|
||||
h.b.kill(h.enemy('enemy_dummy'));
|
||||
assert.ok(h.runUntil(() => h.b.finished, 5), 'the battle ends');
|
||||
assert.equal(h.result().reason, 'cleared');
|
||||
assert.equal(shells().length, 0, 'no shell after the battle');
|
||||
assert.deepEqual(h.b.contentErrors ?? [], []);
|
||||
checkInvariants(h.b);
|
||||
});
|
||||
Reference in new issue
Block a user