feedback2 WC: 乌尔比安 S3 takes his own tile only while he blocks; otherwise the anchor search starts one tile ahead as in 0.1.1 (review of GitHub #33 item 2)

This commit is contained in:
sganggs committed 2026-10-03 23:44:36 +08:00
1 parent 93b0592bff
commit ee70c608dc
2 files changed
+32 -17

No files matched your search

+4 -3
View File
@@ -817,11 +817,12 @@ const KITS = {
mods: mods({ hpPct: num(bb.max_hp), atkPct: num(bb.atk) }),
onStart({ battle, unit }) {
// PRTS 备注 ② — the anchor's target: his own tile while he blocks an enemy (e.g. just after a 突袭 landing),
// else the nearest tile of the skill range (6-1: his own tile and the 6 straight ahead along his direction) with
// an enemy on it, else its farthest tile
// else the nearest tile ahead in the skill range (straight along his direction) with an enemy on it, else the
// farthest one. His own tile is a candidate only while he blocks ("自身所在地块(仅阻挡敌人时)"); not taken: the
// reading of the range's own tile (6-1 starts at [0,0]) as distance 0 for the second rule (a flyer over him)
let stop = 0;
if (!unit.blocking.some((e) => e.alive && e.blockedBy === unit)) {
for (let d = 0; d <= reach; d++) {
for (let d = 1; d <= reach; d++) {
const [r, c] = frontOf(unit.tileR, unit.tileC, unit.dir, d);
// the anchor stops at the field edge and in front of a ground obstacle (crates, roadblocks)
if (!battle.grid.inRect(r, c) || battle.grid.isObstacle(r, c)) break;
+28 -14
View File
@@ -235,9 +235,9 @@ test('乌尔比安 S3: anchor 135 % ATK + stun on the first enemy ahead, moves t
});
test('乌尔比安 S3 while he blocks (e.g. after a 突袭 landing): the anchor lands on his own tile — no 【移动】, no marker (PRTS 备注; GitHub #33)', () => {
// PRTS 乌尔比安 S3 备注: target = his own tile (only while blocking) > the nearest tile of the skill range (6-1, from his own
// tile on) with an enemy > its farthest tile; the 从不混淆的方向 only when the 【移动】 changes his tile
const run = (near) => {
// PRTS 乌尔比安 S3 备注: target = his own tile (only while blocking) > the nearest tile of the skill range with an enemy >
// its farthest tile; the 从不混淆的方向 only when the 【移动】 changes his tile
const setup = (near) => {
const h = makeBattle({
defs: { enemies: { enemy_dummy: dummy(), enemy_fly: dummy('enemy_fly', { motion: 'FLY' }) } },
units: [{ chessId: 'chess_char_5_05_a', row: 9, col: 3 }],
@@ -249,21 +249,35 @@ test('乌尔比安 S3 while he blocks (e.g. after a 突袭 landing): the anchor
const blocked = e0.blockedBy === u;
u.skill.gainSp(1000);
assert.ok(h.runUntil(() => u.skill.active, 2), near);
const anchor = fxOf(h, 'anchor')[0];
assert.deepEqual([anchor[2], anchor[3]], [3, 9], `${near}: the anchor on his own tile`);
assert.equal(tagged(h, 'anchor', e0).length, 1, `${near}: the enemy on his tile is hit`);
return { h, u, e0, far, blocked, anchor: fxOf(h, 'anchor')[0] };
};
{ // blocking the enemy on his tile: the anchor on his own tile, he stays
const { h, u, e0, far, blocked, anchor } = setup('enemy_dummy');
assert.ok(blocked, 'he blocks the enemy on his tile');
assert.deepEqual([anchor[2], anchor[3]], [3, 9], 'the anchor on his own tile');
assert.equal(tagged(h, 'anchor', e0).length, 1, 'the blocked enemy is hit');
assert.ok(e0.s.flags.stun);
assert.equal(tagged(h, 'anchor', far).length, 0, `${near}: 4 tiles ahead, out of the 1.8 radius`);
assert.deepEqual([u.tileR, u.tileC], [9, 3], `${near}: no 【移动】`);
assert.ok(!h.b.allyUnits.some((x) => x.kind === 'token'), `${near}: no 从不混淆的方向`);
assert.equal(tagged(h, 'anchor', far).length, 0, '4 tiles ahead, out of the 1.8 radius');
assert.deepEqual([u.tileR, u.tileC], [9, 3], 'no 【移动】');
assert.ok(!h.b.allyUnits.some((x) => x.kind === 'token'), 'no 从不混淆的方向');
assert.ok(h.runUntil(() => !u.skill.active, 30));
assert.deepEqual([u.tileR, u.tileC], [9, 3]);
clean(h);
return blocked;
};
assert.equal(run('enemy_dummy'), true, 'he blocks the enemy on his tile');
// not blocking, a flyer over him: his own tile is the nearest tile of the skill range with an enemy (distance 0)
assert.equal(run('enemy_fly'), false, 'a flyer is not blocked');
}
{ // not blocking, a flyer over his tile: his own tile is no candidate (only while blocking) — the anchor flies to the
// enemy 4 tiles ahead and he moves there, as in 0.1.1
const { h, u, e0, far, blocked, anchor } = setup('enemy_fly');
assert.ok(!blocked, 'a flyer is not blocked');
assert.deepEqual([anchor[2], anchor[3]], [7, 9], 'the anchor on the enemy ahead');
assert.equal(tagged(h, 'anchor', far).length, 1);
assert.equal(tagged(h, 'anchor', e0).length, 0, 'the flyer over his tile is out of the 1.8 radius');
assert.deepEqual([u.tileR, u.tileC], [9, 7], 'moved onto the anchor tile');
const marker = h.b.allyUnits.find((x) => x.kind === 'token' && x.alive);
assert.ok(marker && marker.tileR === 9 && marker.tileC === 3, 'the marker on his tile');
assert.ok(h.runUntil(() => !u.skill.active, 30));
assert.deepEqual([u.tileR, u.tileC], [9, 3], 'back home');
clean(h);
}
});
test('乌尔比安 T1 本性的坚守 heals per hit taken; T2 血脉的哺养 +HP/ATK per kill (abyssal allies half); elite healing ×1.2', () => {