feedback7 R22-OSIM: 香槟炸弹 no longer goes off on an unrevealed 隐匿 enemy (nor a sleeping one) — it selects like the other contact traps; golden: bond-yanShip-high, coop2-HARD-4 move

Community report relayed by the owner: 「有人反馈香槟炸到没有破隐的隐匿敌人了」. Reproduced: a 隐匿 walker crossing
琳琅诗怀雅's bombs set them off (both kits checked hidden / flying / untargetable only). The rule: PRTS 作战机制 §隐匿
"隐匿效果使得获得该效果的单位无法被任何敌方的能力索敌选中…要选中隐匿的目标,则该单位自身需拥有无视隐匿的效果"; 异常效果 lists
隐匿 and 无敌 among the 无法选择 effects (沉睡 = "无敌且无法行动", gamedata_const ba.sleep). Neither the 香槟炸弹 page nor
琳琅诗怀雅's S2 carries a 无视隐匿 / 无视可选性 note, and the other contact traps of the sim (多萝西's 共振装置, 望's 棋子)
already select through canTargetEnemy.

Now both kits go off on a ground enemy canTargetEnemy accepts (tokens.js CHAMPAGNE_TRIGGER): a 隐匿 enemy sets one off
once it is revealed (反隐) or blocked (its 隐匿 lifts), a sleeping one once it wakes (until now the bomb was spent on it
for no damage). Placement is unchanged (it already aimed at selectable enemies only).

Golden: bond-yanShip-high and coop2-HARD-4 (bombs under 隐匿 enemies of rounds 10–11 — 隐形弩手组长, 访问团强攻冠军,
重弩突袭者 — and sleeping ones of round 7 — 宿主士兵, 粉碎攻坚手 — now wait).

Tests: test/content/feedback7-champagne-stealth.test.js (2; both fail on the parent).
This commit is contained in:
sganggs committed 2026-10-08 20:15:17 +08:00
1 parent 5f98baecc1
commit e733171b13
6 files changed
+94 -33

No files matched your search

@@ -0,0 +1,56 @@
// test/content/feedback7-champagne-stealth.test.js — 琳琅诗怀雅's 香槟炸弹 does not go off on a 隐匿 enemy that is neither
// revealed nor blocked (community report: 「香槟炸到没有破隐的隐匿敌人了」). PRTS 作战机制 §隐匿: "隐匿效果使得获得该效果的单位无法被
// 任何敌方的能力索敌选中" — the bomb's pages carry no 无视隐匿 note, and the other contact traps (多萝西's 共振装置, 望's 棋子)
// select their enemies so too. A revealed (反隐) or blocked one, and every visible ground enemy, still set it off.
// Run: node --test test/content/feedback7-champagne-stealth.test.js
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { makeBattle, enemyRec, checkInvariants } from '../helpers/battleHarness.js';
const TRAP = 'token_10031_swire2_gdtrap';
const trapHits = (h, e) => h.hooksOf('damaged').filter((c) => c.target === e && c.dmg?.tags?.includes('trap'));
test('her bombs: a 隐匿 walker crosses one unharmed; a visible walker after it sets it off', () => {
const h = makeBattle({
timeLimit: 120, autoFinish: false, hooks: ['damaged', 'death'], captureNoisy: true,
defs: { enemies: { e_w: enemyRec({ key: 'e_w', hp: 1e6, speed: 1, def: 0, atk: 0 }) } },
units: [{ uid: 1, chessId: 'chess_char_3_04_a', row: 9, col: 5 }],
});
h.step();
const sw = h.unit(1);
const bombAt = (r, c) => h.b.allyUnits.find((t) => t.alive && t.defId === TRAP && t.tileR === r && t.tileC === c);
for (let i = 0; i < 15 && !bombAt(9, 7); i++) { sw.mem.coins = 3; h.run(2); }
const bomb = bombAt(9, 7);
assert.ok(bomb, 'a bomb on (9,7), on the walkers\' road before her block');
const hidden = h.spawn('e_w', { route: 0 });
h.b.addBuff(hidden, { key: 'test:stealth', persist: true, flags: { stealth: true } });
assert.ok(h.runUntil(() => hidden.x < 6.6, 20), 'it walked over (9,7)');
assert.ok(bomb.alive, 'not set off');
assert.equal(trapHits(h, hidden).length, 0);
const seen = h.spawn('e_w', { route: 0 });
assert.ok(h.runUntil(() => !bomb.alive, 20), 'a visible walker sets it off');
assert.ok(trapHits(h, seen).length > 0 && seen.findBuff('sluggish'));
checkInvariants(h.b);
});
test('a bomb (the token kit) under a standing 隐匿 enemy waits; revealed (反隐), it goes off', () => {
const h = makeBattle({
timeLimit: 30, autoFinish: false, hooks: ['damaged'], captureNoisy: true,
defs: { enemies: { e_d: enemyRec({ key: 'e_d', hp: 1e6, speed: 0, def: 0, atk: 0 }) } },
units: [{ uid: 1, chessId: 'chess_char_3_04_a', row: 12, col: 3 }], enemies: [{ key: 'e_d', pos: [9, 7] }],
});
h.step();
const e = h.b.enemies.find((x) => x.alive);
h.b.addBuff(e, { key: 'test:stealth', persist: true, flags: { stealth: true } });
const bomb = h.b.spawnToken(h.unit(1), TRAP, 9, 7);
assert.ok(bomb);
h.run(2);
assert.ok(bomb.alive && !e.blockedBy, 'a 隐匿 enemy on its tile does not set it off');
assert.equal(trapHits(h, e).length, 0);
h.b.addBuff(e, { key: 'test:reveal', persist: true, flags: { reveal: true } });
h.step(2);
assert.ok(!bomb.alive, 'revealed: it goes off');
assert.ok(trapHits(h, e).length > 0);
checkInvariants(h.b);
});
+19 -26
View File
@@ -1784,48 +1784,41 @@
"round": 10,
"seed": 3858016853,
"waveId": "act1autochess_h03",
"time": 76.07,
"ticks": 2282,
"time": 83.5,
"ticks": 2505,
"reason": "cleared",
"killed": 21,
"total": 21,
"unspawned": 0,
"bossHpLeft": null,
"rngDraws": 10,
"rngDraws": 3,
"errors": {"count":0,"kinds":[]},
"players": {"p1":{"killed":21,"total":21,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":263171,"bossDmg":0,"heal":1471,"deaths":0,"layerGains":{}}},
"players": {"p1":{"killed":21,"total":21,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":0,"dmg":261981,"bossDmg":0,"heal":3087,"deaths":0,"layerGains":{}}},
"units": [
["p1",1,"op","chess_char_4_17_b",1,"uniequip_002_hsguma",3513,1,8,0,0,0,0,0,0],
["p1",2,"op","chess_char_6_03_b",2,"uniequip_002_yu",3700,1,6,0,0,0,0,0,0],
["p1",2,"op","chess_char_6_03_b",2,"uniequip_002_yu",3700,1,6,0,0,0,972,0,1],
["p1",3,"op","chess_char_3_03_b",1,"uniequip_002_swire",1898,1,9,0,0,0,0,0,0],
["p1",4,"op","chess_char_3_04_b",1,"uniequip_002_swire2",2323,1,11,8,64447,0,0,0,0],
["p1",4,"op","chess_char_3_04_b",1,"uniequip_002_swire2",2323,1,11,8,63257,0,0,7,0],
["p1",5,"op","chess_char_1_03_b",1,"uniequip_002_leizi",1391,1,4,0,0,0,0,4,1],
["p1",6,"op","chess_char_2_04_b",1,"uniequip_002_grabds",1270,1,5,0,0,0,0,0,0],
["p1",7,"op","chess_char_5_03_b",2,"uniequip_002_blaze2",632.96,1,12,3,51359,2310,1471,8,2],
["p1",8,"op","chess_char_5_12_b",0,"uniequip_002_dusk",1787,1,7,4,68403,0,0,4,4],
["p1",7,"op","chess_char_5_03_b",2,"uniequip_002_blaze2",1469.32,1,12,3,51359,3089,2115,9,2],
["p1",8,"op","chess_char_5_12_b",0,"uniequip_002_dusk",1787,1,7,4,68403,0,0,5,5],
["p1",9,"op","chess_char_5_23_b",1,"uniequip_002_reckpr",1610,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],
["-","~3","device","trap_1105_accrate",null,null,100,1,3,0,0,0,0,0,null],
["p1","~1","token","enemy_9012_acloon",null,null,17300.16,1,13,4,49667,389,0,2,2],
["p1","~2","token","enemy_9012_acloon",null,null,13634.89,1,14,2,28865,4054,0,1,1],
["p1","~1","token","token_10031_swire2_gdtrap",null,null,1000,0,15,0,0,0,0,0,null],
["p1","~2","token","token_10031_swire2_gdtrap",null,null,1000,1,18,0,0,0,0,0,null],
["p1","~3","token","token_10031_swire2_gdtrap",null,null,1000,0,27,0,0,0,0,0,null],
["p1","~4","token","token_10031_swire2_gdtrap",null,null,1000,0,30,0,0,0,0,0,null],
["p1","~5","token","token_10031_swire2_gdtrap",null,null,1000,0,33,0,0,0,0,0,null],
["p1","~6","token","token_10031_swire2_gdtrap",null,null,1000,0,36,0,0,0,0,0,null],
["p1","~1","token","token_10015_dusk_drgn",null,null,0,0,39,0,430,1997,0,1,null],
["p1","~7","token","token_10031_swire2_gdtrap",null,null,1000,0,41,0,0,0,0,0,null],
["p1","~8","token","token_10031_swire2_gdtrap",null,null,1000,0,42,0,0,0,0,0,null],
["p1","~9","token","token_10031_swire2_gdtrap",null,null,1000,0,44,0,0,0,0,0,null],
["p1","~10","token","token_10031_swire2_gdtrap",null,null,1000,1,46,0,0,0,0,0,null]
["p1","~1","token","enemy_9012_acloon",null,null,17260.25,1,13,4,49667,429,0,2,2],
["p1","~2","token","enemy_9012_acloon",null,null,12970.87,1,14,2,28865,4718,0,1,1],
["p1","~1","token","token_10031_swire2_gdtrap",null,null,1000,1,15,0,0,0,0,0,null],
["p1","~2","token","token_10031_swire2_gdtrap",null,null,1000,0,18,0,0,0,0,0,null],
["p1","~1","token","token_10015_dusk_drgn",null,null,0,0,35,0,430,1997,0,1,null],
["p1","~3","token","token_10031_swire2_gdtrap",null,null,1000,0,39,0,0,0,0,0,null]
],
"enemies": {"enemy_1019_jshoot_2":[7,7,0,1748,47029],"enemy_1381_winman":[9,9,0,0,129890],"enemy_1389_winbab_2":[5,5,0,5215,87091]},
"hooks": [1,46,2282,94,94,188,151,933,22,30,10,8,6,4515,1,4,21,0,1,23,0,0,0],
"events": {"atk":94,"deploy":22,"die":30,"dmg":151,"engage":6,"fx":46,"skill":22,"spawn":46,"status":3},
"fx": {"coin":14,"downed":1,"explode":8,"revive":1,"splash":6,"summon":11,"yanyouFlame":3,"yanyouSummon":2},
"snaps": "663ec4b2 fcbf72b6 e7a436e9 b069f338 26ddf9b5 aebe36fd afb4e8de 79b62d42"
"enemies": {"enemy_1019_jshoot_2":[7,7,0,3530,47029],"enemy_1381_winman":[9,9,0,0,129890],"enemy_1389_winbab_2":[5,5,0,5490,87091]},
"hooks": [1,39,2505,127,127,234,178,1651,22,24,12,12,6,5604,1,12,21,0,1,24,0,0,0],
"events": {"atk":127,"deploy":15,"die":24,"dmg":175,"engage":7,"fx":28,"skill":28,"spawn":39,"status":4},
"fx": {"coin":7,"downed":2,"explode":2,"firewall":1,"revive":1,"splash":6,"summon":4,"yanyouFlame":3,"yanyouSummon":2},
"snaps": "663ec4b2 fcbf72b6 b58a2d82 2eee0ab3 bd3eacca 24e2c6f1 97aa22e6 b2e6492a 0b5b586f"
}
}
}
+1 -1
View File
@@ -738,7 +738,7 @@
"title": {"id":"comment_5","name":"万事俱备","picId":"comment_icon_5","text":"装备配发数量最多"},
"trophies": 3,
"reward": 298,
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":3796247,"gold":135,"itemsEquipped":18,"kills":262,"leaks":36,"lpLost":27,"merges":3,"perfectRounds":9,"refreshes":16},
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":3795677,"gold":135,"itemsEquipped":18,"kills":262,"leaks":36,"lpLost":27,"merges":3,"perfectRounds":9,"refreshes":16},
"lineup": [],
"bonds": ["arcaneShip 0/30","kazimierzShip 0/2","preciShip 0/98","sargonShip 0/106","skillfulShip 0/24","swiftShip 0/8"]
}