feedback5 CB3: an in-place 复活 (M3茧甲, 埃芒加德) starts a deploy-timed skill again, so a 突袭 member with one jumps at once after the revive instead of waiting out the 10 s idle (community report of 2026-10-06, item 44)
Official: PRTS 盟约记录 备注 — "复活" is 退场 + a 0-time / 0-cost redeploy, i.e. a new deployment, after which a deploy-timed
skill ("部署后…秒内") runs again; a 突袭 member counts such a running window as 技能就绪 (bonds/addon/battle.js raidPoll,
GitHub #49 / #109) and jumps when nothing is in its range. Cause: the remake revives in place (fatal hook) — her window, over
by then, stayed over, and only the idle trigger was left (measured: 缄默德克萨斯 S3 jumped 10.00 s after an M3茧甲 / 埃芒加德
revive, 0.23 s after 不屈's real redeploy). Now items/battle.js revivedInPlace also restarts an activateOnDeploy skill on the
next tick: activated anew when its window had ended, its window back to the full duration when it still ran. The SP reset
and the other 部署时 effects of PRTS's form stay unmodelled (§21.21).
Golden: 1 scenario — roster-012: the elite 缄默德克萨斯 is revived in place three times (101 s, 105 s, 113 s) and her S3 runs
again each time (checked instrumented). Tests: test/sim/feedback5-raid-revive.test.js (3; the M3茧甲 / 埃芒加德 jump and the
window cases fail on the parent, 不屈 is the unchanged control). Docs: docs/SIM.md and docs/design/engine.md (fatal hook).
This commit is contained in:
1 parent
5877800a67
commit
3d472e2304
5 files changed
+121
-24
No files matched your search
+20
-20
@@ -720,8 +720,8 @@
|
||||
"round": 10,
|
||||
"seed": 1517795683,
|
||||
"waveId": "act1autochess_h03",
|
||||
"time": 162.6,
|
||||
"ticks": 4878,
|
||||
"time": 161.57,
|
||||
"ticks": 4847,
|
||||
"reason": "cleared",
|
||||
"killed": 99,
|
||||
"total": 100,
|
||||
@@ -730,21 +730,21 @@
|
||||
"rngDraws": 187,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {
|
||||
"p1": {"killed":99,"total":100,"perfect":false,"leaks":1,"leaksUncounted":0,"coins":10,"dmg":983940,"bossDmg":0,"heal":22157,"deaths":7,"layerGains":{"preciShip":8}}
|
||||
"p1": {"killed":99,"total":100,"perfect":false,"leaks":1,"leaksUncounted":0,"coins":10,"dmg":988651,"bossDmg":0,"heal":21802,"deaths":7,"layerGains":{"preciShip":8}}
|
||||
},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_4_17_b",1,"uniequip_002_hsguma",3046.73,1,7,0,237,466,0,20,0],
|
||||
["p1",2,"op","chess_char_4_18_b",1,"uniequip_002_mudrok",6104,1,9,4,57534,2092,2092,32,7],
|
||||
["p1",2,"op","chess_char_4_18_b",1,"uniequip_002_mudrok",6104,1,9,5,65239,2337,2337,37,8],
|
||||
["p1",3,"op","chess_char_4_11_b",1,"uniequip_002_cathy",2644,1,124,0,2731,3521,0,3,1],
|
||||
["p1",4,"op","chess_char_4_19_b",2,"uniequip_002_flamtl",0,0,104,4,45091,4236,0,45,3],
|
||||
["p1",5,"op","chess_char_4_22_b",2,"uniequip_002_svrash",2169,1,122,10,105064,5538,0,27,3],
|
||||
["p1",6,"op","chess_char_4_16_b",2,"uniequip_002_texas2",1619,1,113,3,4767,5745,362,24,3],
|
||||
["p1",4,"op","chess_char_4_19_b",2,"uniequip_002_flamtl",0,0,104,5,40856,4236,0,40,3],
|
||||
["p1",5,"op","chess_char_4_22_b",2,"uniequip_002_svrash",2219,1,122,9,108386,5488,0,27,3],
|
||||
["p1",6,"op","chess_char_4_16_b",2,"uniequip_002_texas2",1619,1,113,4,16046,5745,362,23,5],
|
||||
["p1",7,"op","chess_char_4_10_b",1,"uniequip_002_aroma",1664,1,4,0,0,0,0,0,0],
|
||||
["p1",8,"op","chess_char_4_12_b",2,"uniequip_002_glady",2232,1,5,2,6911,557,557,14,2],
|
||||
["p1",9,"op","chess_char_4_13_b",1,"uniequip_002_gnosis",1989,1,11,20,187170,2441,0,92,38],
|
||||
["p1",10,"op","chess_char_4_14_b",1,"uniequip_002_lionhd",1576,1,13,44,488221,7756,0,57,23],
|
||||
["p1",11,"op","chess_char_4_20_b",2,"uniequip_002_fartth",0,0,6,12,86215,1419,0,28,5],
|
||||
["p1",12,"op","chess_char_4_21_b",1,"uniequip_002_plosis",1534,1,14,0,0,9049,19146,96,2],
|
||||
["p1",8,"op","chess_char_4_12_b",2,"uniequip_002_glady",2232,1,5,1,5724,557,557,13,2],
|
||||
["p1",9,"op","chess_char_4_13_b",1,"uniequip_002_gnosis",1989,1,11,20,179263,2491,0,91,36],
|
||||
["p1",10,"op","chess_char_4_14_b",1,"uniequip_002_lionhd",1526,1,13,43,487394,7656,0,58,23],
|
||||
["p1",11,"op","chess_char_4_20_b",2,"uniequip_002_fartth",0,0,6,12,82773,1419,0,27,5],
|
||||
["p1",12,"op","chess_char_4_21_b",1,"uniequip_002_plosis",1484,1,14,0,0,8599,18546,100,2],
|
||||
["p1",13,"token","token_10041_cathy_catsld",null,null,100,1,17,0,0,0,0,0,null],
|
||||
["p1",14,"token","token_10041_cathy_catsld",null,null,100,1,16,0,0,0,0,0,null],
|
||||
["-","~1","device","trap_1105_accrate",null,null,100,0,1,0,0,0,0,0,null],
|
||||
@@ -760,19 +760,19 @@
|
||||
"enemy_1183_mlasrt": [1,1,0,988,7488],
|
||||
"enemy_1207_sfji_2": [1,1,0,0,16128],
|
||||
"enemy_1208_msfji_2": [4,4,0,0,120],
|
||||
"enemy_1267_nhpbr": [45,45,0,12545,233280],
|
||||
"enemy_1267_nhpbr_2": [24,24,0,8150,152064],
|
||||
"enemy_1267_nhpbr": [45,45,0,12777,233280],
|
||||
"enemy_1267_nhpbr_2": [24,24,0,7400,152064],
|
||||
"enemy_1270_nhstlk": [1,1,0,0,13824],
|
||||
"enemy_1270_nhstlk_2": [15,15,0,6817,276480],
|
||||
"enemy_1270_nhstlk_2": [15,15,0,7030,276480],
|
||||
"enemy_1325_cbgpro_2": [1,1,0,0,5299],
|
||||
"enemy_1425_lrcmra_2": [1,1,0,718,28800],
|
||||
"enemy_1525_blkswb": [1,0,1,11702,37611],
|
||||
"enemy_1525_blkswb": [1,0,1,11702,42321],
|
||||
"enemy_2050_smsha": [1,1,0,1902,46080]
|
||||
},
|
||||
"hooks": [1,122,4878,469,469,1417,1418,521,107,110,87,86,0,15601,1813,20,100,1,1,122,1,0,1],
|
||||
"events": {"atk":626,"bounty":5,"deploy":19,"die":109,"dmg":1410,"engage":10,"fx":241,"heal":213,"layer":1,"leak":1,"skill":175,"spawn":117,"status":929},
|
||||
"fx": {"beam":6,"blink":2,"displace":4,"dodge":1,"explode":4,"explosion":23,"featherArrow":5,"flame":3,"frostNova":38,"garrison":1,"garrisonGrant":1,"healField":2,"overclock":1,"palsy":1,"pull":2,"revive":4,"riposte":1,"rockslide":7,"shieldBreak":8,"slash":23,"summon":1,"swordRain":9,"swordStorm":3,"telegraph":4,"thorns":3,"tornado":2,"tornadoPulse":10,"truesilver":3,"zone":69},
|
||||
"snaps": "a9c24b01 43e8c4cb 9f57bc24 f59bb440 6678caa3 a8a8f019 00aa512d 0d1483f9 2a3527a2 03e0de1a 3bc882ff 0bd6525a bdfd0551 2a029828 bba7125a e653cf29 998295f6"
|
||||
"hooks": [1,122,4847,476,476,1436,1435,526,107,110,88,87,0,16368,1779,26,100,1,1,121,1,0,3],
|
||||
"events": {"atk":634,"bounty":5,"deploy":19,"die":109,"dmg":1425,"engage":10,"fx":269,"heal":217,"layer":1,"leak":1,"skill":177,"spawn":117,"status":920},
|
||||
"fx": {"beam":6,"blink":2,"displace":4,"dodge":3,"explode":5,"explosion":23,"featherArrow":5,"flame":3,"frostNova":36,"garrison":1,"garrisonGrant":1,"healField":2,"overclock":1,"palsy":1,"pull":2,"revive":4,"riposte":3,"rockslide":8,"shieldBreak":10,"slash":24,"summon":1,"swordRain":29,"swordStorm":5,"telegraph":3,"thorns":3,"tornado":2,"tornadoPulse":10,"truesilver":3,"zone":69},
|
||||
"snaps": "a9c24b01 43e8c4cb 9f57bc24 f59bb440 6678caa3 a8a8f019 00aa512d 0d1483f9 2a3527a2 03e0de1a 8e417627 3f822e54 df66a000 eac29e3c 8acf1281 0f15b00b 8758da2f"
|
||||
},
|
||||
"roster-013": {
|
||||
"about": "pass 0 band 5: chess_char_4_23_b chess_char_5_08_a chess_char_5_01_a chess_char_5_05_a chess_char_5_06_a chess_char_5_07_a chess_char_4_24_b chess_char_4_25_b chess_char_4_26_b chess_char_5_02_a chess_char_5_03_a chess_char_5_10_a",
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
// test/sim/feedback5-raid-revive.test.js — community report of 2026-10-06 (item 44) 「突袭盟约的干员如果带被动技能,复活之后不会
|
||||
// 立马突袭出去,还要等突袭CD」. A 突袭 member counts a running deploy-timed skill ("部署后…秒内": 缄默德克萨斯 S1–S3 …) as 技能
|
||||
// 就绪 (bonds/addon/battle.js raidPoll, GitHub #49 / #109), so after a redeploy it jumps at once when nothing is in its range.
|
||||
// PRTS's 复活 (M3茧甲, 埃芒加德) is 退场 + a 0-time / 0-cost redeploy (PRTS 盟约记录 备注) — a new deployment — but the remake
|
||||
// revives in place: her window, over by then, stayed over and she waited out the 10 s idle time. Now an in-place revive
|
||||
// starts a deploy-timed skill again (content/items/battle.js revivedInPlace); 不屈's real redeploy already did.
|
||||
// Run: node --test test/sim/feedback5-raid-revive.test.js
|
||||
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { makeBattle, enemyRec, checkInvariants } from '../helpers/battleHarness.js';
|
||||
|
||||
const TEX = 'chess_char_4_16_a';
|
||||
const DUMMY = { enemy_rv: enemyRec({ key: 'enemy_rv', hp: 1e9, speed: 0, mass: 0, atk: 0 }) };
|
||||
const RAID = { raidShip: { count: 3, active: true, tier: 1, layers: 10 } };
|
||||
|
||||
/**
|
||||
* 缄默德克萨斯 (S3, a 6 s deploy-timed skill) in 突袭 with `extra` (items / band): she jumps to a parked enemy, stays past her
|
||||
* window, the enemy is removed, she is knocked out with nothing in range, a new enemy parks away from her. Returns how long
|
||||
* after the knock-out her next jump comes (null: none within 15 s) and her skill state right after the revive.
|
||||
*/
|
||||
function reviveAndJump({ items, bandId = null, bonds = {} }) {
|
||||
const h = makeBattle({
|
||||
seed: 3, autoFinish: false, timeLimit: 120, hooks: ['deploy', 'death'], defs: { enemies: DUMMY }, bandId,
|
||||
bonds: { ...RAID, ...bonds }, enemies: [{ key: 'enemy_rv', pos: [9, 9] }], units: [{ chessId: TEX, row: 12, col: 3, skillIndex: 2, items }],
|
||||
});
|
||||
h.step();
|
||||
const u = h.unit(TEX);
|
||||
const jumps = () => h.hooksOf('deploy').filter((c) => c.unit === u && !c.initial);
|
||||
assert.ok(h.runUntil(() => jumps().length >= 1, 10), 'her first jump');
|
||||
h.run(8);
|
||||
assert.equal(u.skill.active, false, 'her 6 s window is over');
|
||||
for (const e of h.b.enemies.filter((x) => x.alive)) h.b.kill(e, null);
|
||||
const t0 = h.b.time;
|
||||
h.b.dealDamage(null, u, { amount: 1e9, type: 'true' });
|
||||
h.spawn('enemy_rv', { pos: [12, 9] });
|
||||
h.step();
|
||||
const state = { alive: u.alive, active: u.skill.active, timeLeft: u.skill.timeLeft };
|
||||
const n = jumps().length;
|
||||
const jumped = h.runUntil(() => jumps().length > n && u.tileR === 12, 15);
|
||||
checkInvariants(h.b);
|
||||
return { after: jumped ? h.b.time - t0 : null, state, u, h };
|
||||
}
|
||||
|
||||
test('M3茧甲 / 埃芒加德 revive 缄默德克萨斯 in place: her deploy-timed S3 runs again and she jumps at once (until 0.2.0 only after the 10 s idle)', () => {
|
||||
for (const [label, opts] of [['M3茧甲', { items: ['chess_item_4_12_e_a'] }], ['埃芒加德', { bandId: 'band_ermengard' }]]) {
|
||||
const { after, state } = reviveAndJump(opts);
|
||||
assert.ok(state.alive, `${label}: revived in place`);
|
||||
assert.ok(state.active, `${label}: her deploy-timed S3 runs again`);
|
||||
assert.ok(after != null && after < 1, `${label}: jumped ${after?.toFixed(2)} s after the knock-out`);
|
||||
}
|
||||
});
|
||||
|
||||
test('不屈\'s 立刻重新部署 (a real redeploy) already jumped at once — unchanged', () => {
|
||||
const { after } = reviveAndJump({ bonds: { indomShip: { count: 2, active: true, tier: 1, layers: 300 } } });
|
||||
assert.ok(after != null && after < 1, `jumped ${after?.toFixed(2)} s after the knock-out`);
|
||||
});
|
||||
|
||||
test('an in-place revive inside the window sets it back to its full length; 砾 revived by M3茧甲 gets a fresh barrier', () => {
|
||||
const h = makeBattle({ seed: 3, autoFinish: false, timeLimit: 60, units: [{ chessId: TEX, row: 12, col: 3, skillIndex: 2, items: ['chess_item_4_12_e_a'] }] });
|
||||
h.step();
|
||||
const u = h.unit(TEX);
|
||||
h.run(3);
|
||||
assert.ok(u.skill.active && u.skill.timeLeft < u.skill.duration - 2, 'half-way through the window');
|
||||
h.b.dealDamage(null, u, { amount: 1e9, type: 'true' });
|
||||
h.step(2);
|
||||
assert.ok(u.alive && u.skill.active && u.skill.timeLeft > u.skill.duration - 0.2, `back to the full ${u.skill.duration} s (${u.skill.timeLeft.toFixed(2)})`);
|
||||
checkInvariants(h.b);
|
||||
|
||||
const g = makeBattle({ seed: 3, autoFinish: false, timeLimit: 60, units: [{ chessId: 'chess_char_2_12_a', row: 10, col: 4, items: ['chess_item_4_12_e_a'] }] });
|
||||
g.step();
|
||||
const gr = g.unit('chess_char_2_12_a');
|
||||
g.run(12);
|
||||
assert.ok(!gr.findBuff('gravel:rats'), 'the deployment barrier has run out');
|
||||
g.b.dealDamage(null, gr, { amount: 1e9, type: 'true' });
|
||||
g.step(2);
|
||||
assert.ok(gr.alive && gr.findBuff('gravel:rats')?.shield > 0, 'a fresh barrier after the revive');
|
||||
checkInvariants(g.b);
|
||||
});
|
||||
Reference in new issue
Block a user